expando-loss.html (8761B)
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 <!DOCTYPE html> 7 <html> 8 <head> 9 <meta charset="utf-8"> 10 <link rel="stylesheet" href="../../resources/js-test-style.css"/> 11 <script src="../../js/js-test-pre.js"></script> 12 <script src="../../js/webgl-test-utils.js"></script> 13 <title>WebGL Object Expandos Conformance Test</title> 14 </head> 15 <body> 16 <div id="description"></div> 17 <div id="console"></div> 18 <canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas> 19 <script> 20 "use strict"; 21 description("This test verifies that WebGL object expandos are preserved across garbage collections."); 22 23 var wtu = WebGLTestUtils; 24 var canvas = document.getElementById("canvas"); 25 var gl = wtu.create3DContext(canvas, {antialias: false}); 26 27 // Helpers that set expandos and verify they are set to the correct value. 28 var expandoValue = "WebGL is awesome!" 29 function setTestExpandos(instance) { 30 instance.expando1 = expandoValue; 31 instance.expando2 = { subvalue : expandoValue }; 32 } 33 function verifyTestExpandos(instance, msg) { 34 assertMsg(instance.expando1 === expandoValue, msg + ": Expect basic expando to survive despite GC."); 35 assertMsg(instance.expando2 && instance.expando2.subvalue === expandoValue, msg + ": Expect subobject expando to survive despite GC."); 36 } 37 38 // Tests that we don't get expando loss for bound resources where the 39 // only remaining reference is internal to WebGL 40 function testBasicBindings() { 41 debug('Basic Bindings'); 42 43 // Test data that describes how to create, bind, and retrieve an object off of the context 44 var glProt = Object.getPrototypeOf(gl); 45 var simpleData = [ 46 { 47 creationFn: glProt.createTexture, 48 bindFn: glProt.bindTexture, 49 bindConstant: glProt.TEXTURE_2D, 50 retrieveConstant: glProt.TEXTURE_BINDING_2D, 51 name: "TEXTURE_BINDING_2D", 52 }, 53 { 54 creationFn: glProt.createFramebuffer, 55 bindFn: glProt.bindFramebuffer, 56 bindConstant: glProt.FRAMEBUFFER, 57 retrieveConstant: glProt.FRAMEBUFFER_BINDING, 58 name: "FRAMEBUFFER_BINDING", 59 }, 60 { 61 creationFn: glProt.createRenderbuffer, 62 bindFn: glProt.bindRenderbuffer, 63 bindConstant: glProt.RENDERBUFFER, 64 retrieveConstant: glProt.RENDERBUFFER_BINDING, 65 name: "RENDERBUFFER_BINDING", 66 }, 67 { 68 creationFn: glProt.createBuffer, 69 bindFn: glProt.bindBuffer, 70 bindConstant: glProt.ELEMENT_ARRAY_BUFFER, 71 retrieveConstant: glProt.ELEMENT_ARRAY_BUFFER_BINDING, 72 name: "ELEMENT_ARRAY_BUFFER_BINDING", 73 }, 74 { 75 creationFn: glProt.createBuffer, 76 bindFn: glProt.bindBuffer, 77 bindConstant: glProt.ARRAY_BUFFER, 78 retrieveConstant: glProt.ARRAY_BUFFER_BINDING, 79 name: "ARRAY_BUFFER_BINDING", 80 }, 81 { 82 creationFn: glProt.createTexture, 83 bindFn: glProt.bindTexture, 84 bindConstant: glProt.TEXTURE_CUBE_MAP, 85 retrieveConstant: glProt.TEXTURE_BINDING_CUBE_MAP, 86 name: "TEXTURE_BINDING_CUBE_MAP", 87 }, 88 ]; 89 90 simpleData.forEach(function(test) { 91 var instance = test.creationFn.apply(gl, []); 92 var msg = "getParameter(" + test.name + ")"; 93 setTestExpandos(instance); 94 95 test.bindFn.apply(gl, [test.bindConstant, instance]); 96 assertMsg(instance === gl.getParameter(test.retrieveConstant), msg + " returns instance that was bound."); 97 98 // Garbage collect Javascript references. Remaining references should be internal to WebGL. 99 instance = null; 100 webglHarnessCollectGarbage(); 101 102 verifyTestExpandos(gl.getParameter(test.retrieveConstant), msg); 103 }); 104 105 debug(''); 106 } 107 108 // Attach a couple of shaders to a program and verify no expando loss when you call 109 // getAttachedShaders and getParameter(CURRENT_PROGRAM). 110 function testProgramsAndShaders() { 111 debug('Programs and Shaders'); 112 113 var vs = wtu.loadShader(gl, wtu.simpleVertexShader, gl.VERTEX_SHADER); 114 setTestExpandos(vs); 115 116 var fs = wtu.loadShader(gl, wtu.simpleColorFragmentShader, gl.FRAGMENT_SHADER); 117 setTestExpandos(fs); 118 119 var program = wtu.setupProgram(gl, [vs, fs]); 120 setTestExpandos(program); 121 assertMsg(program === gl.getParameter(gl.CURRENT_PROGRAM), "getParameter(gl.CURRENT_PROGRAM) return instance set with useProgram"); 122 123 var attachedShaders = gl.getAttachedShaders(program); 124 assertMsg(attachedShaders.indexOf(vs) !== -1, "Vertex shader instance found in getAttachedShaders"); 125 assertMsg(attachedShaders.indexOf(fs) !== -1, "Fragment shader instance found in getAttachedShaders"); 126 127 // Garbage collect Javascript references. Remaining references should be internal to WebGL. 128 attachedShaders = null; 129 program = null; 130 vs = null; 131 fs = null; 132 webglHarnessCollectGarbage(); 133 134 var currentProgram = gl.getParameter(gl.CURRENT_PROGRAM); 135 verifyTestExpandos(currentProgram, "Current program"); 136 shouldBeType(currentProgram, 'WebGLProgram'); 137 138 var retrievedShaders = gl.getAttachedShaders(currentProgram); 139 verifyTestExpandos(retrievedShaders[0], "Shader[0]"); 140 shouldBeType(retrievedShaders[0], "WebGLShader"); 141 verifyTestExpandos(retrievedShaders[1], "Shader[1]"); 142 shouldBeType(retrievedShaders[1], "WebGLShader"); 143 144 debug(''); 145 } 146 147 // Attach a buffer via vertexAttribPointer and verify no expando loss when you call getVertexAttrib. 148 function testVertexAttributeBuffers() { 149 debug('Vertex Attribute Buffers'); 150 151 var program = wtu.setupSimpleColorProgram(gl); 152 var position = gl.getAttribLocation(program, "vPosition"); 153 154 var buffer = gl.createBuffer(); 155 setTestExpandos(buffer); 156 gl.bindBuffer(gl.ARRAY_BUFFER, buffer); 157 gl.vertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0); 158 assertMsg(buffer === gl.getVertexAttrib(position, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING), 159 "getVertexAttrib(VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) return instance set with vertexAttribPointer"); 160 gl.bindBuffer(gl.ARRAY_BUFFER, null); 161 162 // Garbage collect Javascript references. Remaining references should be internal to WebGL. 163 buffer = null; 164 program = null; 165 webglHarnessCollectGarbage(); 166 167 var retrievedBuffer = gl.getVertexAttrib(position, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING); 168 verifyTestExpandos(retrievedBuffer, "Vertex Attribute Buffer"); 169 shouldBeType(retrievedBuffer, 'WebGLBuffer'); 170 171 debug(''); 172 } 173 174 // Attach renderbuffers to framebuffers and verify no expando loss ocurrs when you call 175 // getFramebufferAttachmentParameter 176 function testFrameBufferAttachments() { 177 debug('FrameBuffer Attachments'); 178 179 var framebuffer = gl.createFramebuffer(); 180 gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); 181 var attachments = [ 182 { enum: gl.COLOR_ATTACHMENT0, name: "COLOR_ATTACHMENT0" }, 183 { enum: gl.DEPTH_ATTACHMENT, name: "DEPTH_ATTACHMENT" }, 184 { enum: gl.STENCIL_ATTACHMENT, name: "STENCIL_ATTACHMENT" }, 185 { enum: gl.DEPTH_STENCIL_ATTACHMENT,name: "DEPTH_STENCIL_ATTACHMENT" }, 186 ]; 187 188 // Attach a renderbuffer to all attachment points. 189 attachments.forEach(function(attachment) { 190 var renderbuffer = gl.createRenderbuffer(); 191 gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer); 192 gl.bindRenderbuffer(gl.RENDERBUFFER, null); 193 setTestExpandos(renderbuffer); 194 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment.enum, gl.RENDERBUFFER, renderbuffer); 195 assertMsg(renderbuffer === gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, attachment.enum, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME), 196 "getFramebufferAttachmentParameter(" + attachment.name + ") returns instance set with framebufferRenderbuffer"); 197 renderbuffer = null; 198 }); 199 200 // Garbage collect Javascript references. Remaining references should be internal to WebGL. 201 webglHarnessCollectGarbage(); 202 203 // Verify all attached renderbuffers have expandos. 204 attachments.forEach(function(attachment) { 205 var retrievedRenderbuffer = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, attachment.enum, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); 206 verifyTestExpandos(retrievedRenderbuffer, attachment.name); 207 shouldBeType(retrievedRenderbuffer, 'WebGLRenderbuffer'); 208 }); 209 210 debug(''); 211 } 212 213 // Run tests 214 testBasicBindings(); 215 testProgramsAndShaders(); 216 testVertexAttributeBuffers(); 217 testFrameBufferAttachments(); 218 219 var successfullyParsed = true; 220 </script> 221 <script src="../../js/js-test-post.js"></script> 222 </body> 223 </html>