Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | GLSLConformanceTester = (function(){ |
michael@0 | 2 | |
michael@0 | 3 | var wtu = WebGLTestUtils; |
michael@0 | 4 | var defaultVertexShader = [ |
michael@0 | 5 | "attribute vec4 vPosition;", |
michael@0 | 6 | "void main()", |
michael@0 | 7 | "{", |
michael@0 | 8 | " gl_Position = vPosition;", |
michael@0 | 9 | "}" |
michael@0 | 10 | ].join('\n'); |
michael@0 | 11 | |
michael@0 | 12 | var defaultFragmentShader = [ |
michael@0 | 13 | "precision mediump float;", |
michael@0 | 14 | "void main()", |
michael@0 | 15 | "{", |
michael@0 | 16 | " gl_FragColor = vec4(1.0,0.0,0.0,1.0);", |
michael@0 | 17 | "}" |
michael@0 | 18 | ].join('\n'); |
michael@0 | 19 | |
michael@0 | 20 | function log(msg) { |
michael@0 | 21 | if (window.console && window.console.log) { |
michael@0 | 22 | window.console.log(msg); |
michael@0 | 23 | } |
michael@0 | 24 | } |
michael@0 | 25 | |
michael@0 | 26 | var vShaderDB = {}; |
michael@0 | 27 | var fShaderDB = {}; |
michael@0 | 28 | |
michael@0 | 29 | /** |
michael@0 | 30 | * vShaderSource: the source code for vertex shader |
michael@0 | 31 | * vShaderSuccess: true if vertex shader compiliation should |
michael@0 | 32 | * succeed. |
michael@0 | 33 | * fShaderSource: the source code for fragment shader |
michael@0 | 34 | * fShaderSuccess: true if fragment shader compiliation should |
michael@0 | 35 | * succeed. |
michael@0 | 36 | * linkSuccess: true of link should succeed |
michael@0 | 37 | * passMsg: msg to describe success condition. |
michael@0 | 38 | * render: if true render to unit quad. Green = success |
michael@0 | 39 | * |
michael@0 | 40 | */ |
michael@0 | 41 | function runOneTest(gl, info) { |
michael@0 | 42 | var passMsg = info.passMsg |
michael@0 | 43 | debug("test: " + passMsg); |
michael@0 | 44 | |
michael@0 | 45 | var console = document.getElementById("console"); |
michael@0 | 46 | |
michael@0 | 47 | if (info.vShaderSource === undefined) { |
michael@0 | 48 | if (info.vShaderId) { |
michael@0 | 49 | info.vShaderSource = document.getElementById(info.vShaderId).text; |
michael@0 | 50 | } else { |
michael@0 | 51 | info.vShader = 'defaultVertexShader'; |
michael@0 | 52 | info.vShaderSource = defaultVertexShader; |
michael@0 | 53 | } |
michael@0 | 54 | } |
michael@0 | 55 | if (info.fShaderSource === undefined) { |
michael@0 | 56 | if (info.fShaderId) { |
michael@0 | 57 | info.fShaderSource = document.getElementById(info.fShaderId).text; |
michael@0 | 58 | } else { |
michael@0 | 59 | info.fShader = 'defaultFragmentShader'; |
michael@0 | 60 | info.fShaderSource = defaultFragmentShader; |
michael@0 | 61 | } |
michael@0 | 62 | } |
michael@0 | 63 | |
michael@0 | 64 | var vLabel = (info.vShaderSource == defaultVertexShader ? "default" : "test") + " vertex shader"; |
michael@0 | 65 | var fLabel = (info.fShaderSource == defaultFragmentShader ? "default" : "test") + " fragment shader"; |
michael@0 | 66 | |
michael@0 | 67 | var vSource = info.vShaderPrep ? info.vShaderPrep(info.vShaderSource) : |
michael@0 | 68 | info.vShaderSource; |
michael@0 | 69 | |
michael@0 | 70 | wtu.addShaderSource(console, vLabel, vSource); |
michael@0 | 71 | |
michael@0 | 72 | // Reuse identical shaders so we test shared shader. |
michael@0 | 73 | var vShader = vShaderDB[vSource]; |
michael@0 | 74 | if (!vShader) { |
michael@0 | 75 | vShader = wtu.loadShader(gl, vSource, gl.VERTEX_SHADER); |
michael@0 | 76 | if (info.vShaderTest) { |
michael@0 | 77 | if (!info.vShaderTest(vShader)) { |
michael@0 | 78 | testFailed("[vertex shader test] " + passMsg); |
michael@0 | 79 | return; |
michael@0 | 80 | } |
michael@0 | 81 | } |
michael@0 | 82 | // As per GLSL 1.0.17 10.27 we can only check for success on |
michael@0 | 83 | // compileShader, not failure. |
michael@0 | 84 | if (info.vShaderSuccess && !vShader) { |
michael@0 | 85 | testFailed("[unexpected vertex shader compile status] (expected: " + |
michael@0 | 86 | info.vShaderSuccess + ") " + passMsg); |
michael@0 | 87 | } |
michael@0 | 88 | // Save the shaders so we test shared shader. |
michael@0 | 89 | if (vShader) { |
michael@0 | 90 | vShaderDB[vSource] = vShader; |
michael@0 | 91 | } |
michael@0 | 92 | } |
michael@0 | 93 | |
michael@0 | 94 | var fSource = info.fShaderPrep ? info.fShaderPrep(info.fShaderSource) : |
michael@0 | 95 | info.fShaderSource; |
michael@0 | 96 | |
michael@0 | 97 | wtu.addShaderSource(console, fLabel, fSource); |
michael@0 | 98 | |
michael@0 | 99 | // Reuse identical shaders so we test shared shader. |
michael@0 | 100 | var fShader = fShaderDB[fSource]; |
michael@0 | 101 | if (!fShader) { |
michael@0 | 102 | fShader = wtu.loadShader(gl, fSource, gl.FRAGMENT_SHADER); |
michael@0 | 103 | if (info.fShaderTest) { |
michael@0 | 104 | if (!info.fShaderTest(fShader)) { |
michael@0 | 105 | testFailed("[fragment shdaer test] " + passMsg); |
michael@0 | 106 | return; |
michael@0 | 107 | } |
michael@0 | 108 | } |
michael@0 | 109 | //debug(fShader == null ? "fail" : "succeed"); |
michael@0 | 110 | // As per GLSL 1.0.17 10.27 we can only check for success on |
michael@0 | 111 | // compileShader, not failure. |
michael@0 | 112 | if (info.fShaderSuccess && !fShader) { |
michael@0 | 113 | testFailed("[unexpected fragment shader compile status] (expected: " + |
michael@0 | 114 | info.fShaderSuccess + ") " + passMsg); |
michael@0 | 115 | return; |
michael@0 | 116 | } |
michael@0 | 117 | // Safe the shaders so we test shared shader. |
michael@0 | 118 | if (fShader) { |
michael@0 | 119 | fShaderDB[fSource] = fShader; |
michael@0 | 120 | } |
michael@0 | 121 | } |
michael@0 | 122 | |
michael@0 | 123 | if (vShader && fShader) { |
michael@0 | 124 | var program = gl.createProgram(); |
michael@0 | 125 | gl.attachShader(program, vShader); |
michael@0 | 126 | gl.attachShader(program, fShader); |
michael@0 | 127 | gl.bindAttribLocation(program, 0, "vPosition"); |
michael@0 | 128 | gl.bindAttribLocation(program, 1, "texCoord0"); |
michael@0 | 129 | gl.linkProgram(program); |
michael@0 | 130 | var linked = (gl.getProgramParameter(program, gl.LINK_STATUS) != 0); |
michael@0 | 131 | if (!linked) { |
michael@0 | 132 | var error = gl.getProgramInfoLog(program); |
michael@0 | 133 | log("*** Error linking program '"+program+"':"+error); |
michael@0 | 134 | } |
michael@0 | 135 | if (linked != info.linkSuccess) { |
michael@0 | 136 | testFailed("[unexpected link status] " + passMsg); |
michael@0 | 137 | return; |
michael@0 | 138 | } |
michael@0 | 139 | } else { |
michael@0 | 140 | if (info.linkSuccess) { |
michael@0 | 141 | testFailed("[link failed] " + passMsg); |
michael@0 | 142 | return; |
michael@0 | 143 | } |
michael@0 | 144 | } |
michael@0 | 145 | |
michael@0 | 146 | if (!info.render) { |
michael@0 | 147 | testPassed(passMsg); |
michael@0 | 148 | return; |
michael@0 | 149 | } |
michael@0 | 150 | |
michael@0 | 151 | gl.useProgram(program); |
michael@0 | 152 | wtu.setupUnitQuad(gl); |
michael@0 | 153 | wtu.drawQuad(gl); |
michael@0 | 154 | |
michael@0 | 155 | var div = document.createElement("div"); |
michael@0 | 156 | div.className = "testimages"; |
michael@0 | 157 | wtu.insertImage(div, "result", wtu.makeImage(gl.canvas)); |
michael@0 | 158 | div.appendChild(document.createElement('br')); |
michael@0 | 159 | console.appendChild(div); |
michael@0 | 160 | wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green", 0); |
michael@0 | 161 | } |
michael@0 | 162 | |
michael@0 | 163 | function runTests(shaderInfos) { |
michael@0 | 164 | var wtu = WebGLTestUtils; |
michael@0 | 165 | var canvas = document.createElement('canvas'); |
michael@0 | 166 | canvas.width = 32; |
michael@0 | 167 | canvas.height = 32; |
michael@0 | 168 | var gl = wtu.create3DContext(canvas); |
michael@0 | 169 | if (!gl) { |
michael@0 | 170 | testFailed("context does not exist"); |
michael@0 | 171 | finishTest(); |
michael@0 | 172 | return; |
michael@0 | 173 | } |
michael@0 | 174 | |
michael@0 | 175 | for (var ii = 0; ii < shaderInfos.length; ++ii) { |
michael@0 | 176 | runOneTest(gl, shaderInfos[ii]); |
michael@0 | 177 | } |
michael@0 | 178 | |
michael@0 | 179 | finishTest(); |
michael@0 | 180 | }; |
michael@0 | 181 | |
michael@0 | 182 | function loadExternalShaders(filename, passMsg) { |
michael@0 | 183 | var shaderInfos = []; |
michael@0 | 184 | var lines = wtu.readFileList(filename); |
michael@0 | 185 | for (var ii = 0; ii < lines.length; ++ii) { |
michael@0 | 186 | var info = { |
michael@0 | 187 | vShaderSource: defaultVertexShader, |
michael@0 | 188 | vShaderSuccess: true, |
michael@0 | 189 | fShaderSource: defaultFragmentShader, |
michael@0 | 190 | fShaderSuccess: true, |
michael@0 | 191 | linkSuccess: true, |
michael@0 | 192 | }; |
michael@0 | 193 | |
michael@0 | 194 | var line = lines[ii]; |
michael@0 | 195 | var files = line.split(/ +/); |
michael@0 | 196 | var passMsg = ""; |
michael@0 | 197 | for (var jj = 0; jj < files.length; ++jj) { |
michael@0 | 198 | var file = files[jj]; |
michael@0 | 199 | var shaderSource = wtu.readFile(file); |
michael@0 | 200 | var firstLine = shaderSource.split("\n")[0]; |
michael@0 | 201 | var success = undefined; |
michael@0 | 202 | if (firstLine.indexOf("fail") >= 0) { |
michael@0 | 203 | success = false; |
michael@0 | 204 | } else if (firstLine.indexOf("succeed") >= 0) { |
michael@0 | 205 | success = true; |
michael@0 | 206 | } |
michael@0 | 207 | if (success === undefined) { |
michael@0 | 208 | testFailed("bad first line in " + file + ":" + firstLine); |
michael@0 | 209 | continue; |
michael@0 | 210 | } |
michael@0 | 211 | if (!wtu.startsWith(firstLine, "// ")) { |
michael@0 | 212 | testFailed("bad first line in " + file + ":" + firstLine); |
michael@0 | 213 | continue; |
michael@0 | 214 | } |
michael@0 | 215 | passMsg = passMsg + (passMsg.length ? ", " : "") + firstLine.substr(3); |
michael@0 | 216 | if (wtu.endsWith(file, ".vert")) { |
michael@0 | 217 | info.vShaderSource = shaderSource; |
michael@0 | 218 | info.vShaderSuccess = success; |
michael@0 | 219 | } else if (wtu.endsWith(file, ".frag")) { |
michael@0 | 220 | info.fShaderSource = shaderSource; |
michael@0 | 221 | info.fShaderSuccess = success; |
michael@0 | 222 | } |
michael@0 | 223 | } |
michael@0 | 224 | info.linkSuccess = info.vShaderSuccess && info.fShaderSuccess; |
michael@0 | 225 | info.passMsg = passMsg; |
michael@0 | 226 | shaderInfos.push(info); |
michael@0 | 227 | } |
michael@0 | 228 | return shaderInfos; |
michael@0 | 229 | } |
michael@0 | 230 | |
michael@0 | 231 | function getSource(elem) { |
michael@0 | 232 | var str = elem.text; |
michael@0 | 233 | return str.replace(/^\s*/, '').replace(/\s*$/, ''); |
michael@0 | 234 | } |
michael@0 | 235 | |
michael@0 | 236 | function getPassMessage(source) { |
michael@0 | 237 | var lines = source.split('\n'); |
michael@0 | 238 | return lines[0].substring(3); |
michael@0 | 239 | } |
michael@0 | 240 | |
michael@0 | 241 | function getSuccess(msg) { |
michael@0 | 242 | if (msg.indexOf("fail") >= 0) { |
michael@0 | 243 | return false; |
michael@0 | 244 | } |
michael@0 | 245 | if (msg.indexOf("succeed") >= 0) { |
michael@0 | 246 | return true; |
michael@0 | 247 | } |
michael@0 | 248 | testFailed("bad test description. Must have 'fail' or 'success'"); |
michael@0 | 249 | } |
michael@0 | 250 | |
michael@0 | 251 | function setupTest() { |
michael@0 | 252 | var vShaderElem = document.getElementById('vertexShader'); |
michael@0 | 253 | var vShaderSource = defaultVertexShader; |
michael@0 | 254 | var vShaderSuccess = true; |
michael@0 | 255 | |
michael@0 | 256 | var fShaderElem = document.getElementById('fragmentShader'); |
michael@0 | 257 | var fShaderSource = defaultFragmentShader; |
michael@0 | 258 | var fShaderSuccess = true; |
michael@0 | 259 | |
michael@0 | 260 | var passMsg = undefined; |
michael@0 | 261 | |
michael@0 | 262 | if (vShaderElem) { |
michael@0 | 263 | vShaderSource = getSource(vShaderElem); |
michael@0 | 264 | passMsg = getPassMessage(vShaderSource); |
michael@0 | 265 | vShaderSuccess = getSuccess(passMsg); |
michael@0 | 266 | } |
michael@0 | 267 | |
michael@0 | 268 | if (fShaderElem) { |
michael@0 | 269 | fShaderSource = getSource(fShaderElem); |
michael@0 | 270 | passMsg = getPassMessage(fShaderSource); |
michael@0 | 271 | fShaderSuccess = getSuccess(passMsg); |
michael@0 | 272 | } |
michael@0 | 273 | |
michael@0 | 274 | var linkSuccess = vShaderSuccess && fShaderSuccess; |
michael@0 | 275 | |
michael@0 | 276 | if (passMsg === undefined) { |
michael@0 | 277 | testFailed("no test shader found."); |
michael@0 | 278 | finishTest(); |
michael@0 | 279 | return; |
michael@0 | 280 | } |
michael@0 | 281 | |
michael@0 | 282 | var info = { |
michael@0 | 283 | vShaderSource: vShaderSource, |
michael@0 | 284 | vShaderSuccess: vShaderSuccess, |
michael@0 | 285 | fShaderSource: fShaderSource, |
michael@0 | 286 | fShaderSuccess: fShaderSuccess, |
michael@0 | 287 | linkSuccess: linkSuccess, |
michael@0 | 288 | passMsg: passMsg |
michael@0 | 289 | }; |
michael@0 | 290 | |
michael@0 | 291 | return info; |
michael@0 | 292 | } |
michael@0 | 293 | |
michael@0 | 294 | function runTest() { |
michael@0 | 295 | var info = setupTest(); |
michael@0 | 296 | description(info.passMsg); |
michael@0 | 297 | runTests([info]); |
michael@0 | 298 | } |
michael@0 | 299 | |
michael@0 | 300 | function runRenderTests(tests) { |
michael@0 | 301 | for (var ii = 0; ii < tests.length; ++ii) { |
michael@0 | 302 | tests[ii].render = true |
michael@0 | 303 | } |
michael@0 | 304 | runTests(tests); |
michael@0 | 305 | } |
michael@0 | 306 | |
michael@0 | 307 | function runRenderTest() { |
michael@0 | 308 | var info = setupTest(); |
michael@0 | 309 | description(info.passMsg); |
michael@0 | 310 | runRenderTests([info]); |
michael@0 | 311 | } |
michael@0 | 312 | |
michael@0 | 313 | return { |
michael@0 | 314 | runTest: runTest, |
michael@0 | 315 | runTests: runTests, |
michael@0 | 316 | runRenderTest: runRenderTest, |
michael@0 | 317 | runRenderTests: runRenderTests, |
michael@0 | 318 | loadExternalShaders: loadExternalShaders, |
michael@0 | 319 | |
michael@0 | 320 | none: false, |
michael@0 | 321 | }; |
michael@0 | 322 | }()); |