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