Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / webgl / src / sdk / tests / conformance / resources / glsl-conformance-test.js
1 /*
2 ** Copyright (c) 2012 The Khronos Group Inc.
3 **
4 ** Permission is hereby granted, free of charge, to any person obtaining a
5 ** copy of this software and/or associated documentation files (the
6 ** "Materials"), to deal in the Materials without restriction, including
7 ** without limitation the rights to use, copy, modify, merge, publish,
8 ** distribute, sublicense, and/or sell copies of the Materials, and to
9 ** permit persons to whom the Materials are furnished to do so, subject to
10 ** the following conditions:
11 **
12 ** The above copyright notice and this permission notice shall be included
13 ** in all copies or substantial portions of the Materials.
14 **
15 ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
22 */
23 GLSLConformanceTester = (function(){
24
25 var wtu = WebGLTestUtils;
26 var defaultVertexShader = [
27   "attribute vec4 vPosition;",
28   "void main()",
29   "{",
30   "    gl_Position = vPosition;",
31   "}"
32 ].join('\n');
33
34 var defaultFragmentShader = [
35   "precision mediump float;",
36   "void main()",
37   "{",
38   "    gl_FragColor = vec4(1.0,0.0,0.0,1.0);",
39   "}"
40 ].join('\n');
41
42 function log(msg) {
43   if (window.console && window.console.log) {
44     window.console.log(msg);
45   }
46 }
47
48 var vShaderDB = {};
49 var fShaderDB = {};
50
51 /**
52  * vShaderSource: the source code for vertex shader
53  * vShaderSuccess: true if vertex shader compilation should
54  *   succeed.
55  * fShaderSource: the source code for fragment shader
56  * fShaderSuccess: true if fragment shader compilation should
57  *   succeed.
58  * linkSuccess: true of link should succeed
59  * passMsg: msg to describe success condition.
60  * render: if true render to unit quad. Green = success
61  *
62  */
63 function runOneTest(gl, info) {
64   var passMsg = info.passMsg
65   debug("");
66   debug("test: " + passMsg);
67
68   var consoleDiv = document.getElementById("console");
69
70   if (info.vShaderSource === undefined) {
71     if (info.vShaderId) {
72       info.vShaderSource = document.getElementById(info.vShaderId).text;
73     } else {
74       info.vShader = 'defaultVertexShader';
75       info.vShaderSource = defaultVertexShader;
76     }
77   }
78   if (info.fShaderSource === undefined) {
79     if (info.fShaderId) {
80       info.fShaderSource = document.getElementById(info.fShaderId).text;
81     } else {
82       info.fShader = 'defaultFragmentShader';
83       info.fShaderSource = defaultFragmentShader;
84     }
85   }
86
87   var vLabel = (info.vShaderSource == defaultVertexShader ? "default" : "test") + " vertex shader";
88   var fLabel = (info.fShaderSource == defaultFragmentShader ? "default" : "test") + " fragment shader";
89
90   var vSource = info.vShaderPrep ? info.vShaderPrep(info.vShaderSource) :
91     info.vShaderSource;
92
93   wtu.addShaderSource(consoleDiv, vLabel, vSource);
94
95   // Reuse identical shaders so we test shared shader.
96   var vShader = vShaderDB[vSource];
97   if (!vShader) {
98     vShader = wtu.loadShader(gl, vSource, gl.VERTEX_SHADER);
99     if (info.vShaderTest) {
100       if (!info.vShaderTest(vShader)) {
101         testFailed("[vertex shader test] " + passMsg);
102         return;
103       }
104     }
105     // As per GLSL 1.0.17 10.27 we can only check for success on
106     // compileShader, not failure.
107     if (!info.ignoreResults && info.vShaderSuccess && !vShader) {
108       testFailed("[unexpected vertex shader compile status] (expected: " +
109                  info.vShaderSuccess + ") " + passMsg);
110     }
111     // Save the shaders so we test shared shader.
112     if (vShader) {
113       vShaderDB[vSource] = vShader;
114     }
115   }
116
117   var debugShaders = gl.getExtension('WEBGL_debug_shaders');
118   if (debugShaders && vShader) {
119     wtu.addShaderSource(consoleDiv, vLabel + " translated for driver",
120                         debugShaders.getTranslatedShaderSource(vShader));
121   }
122
123   var fSource = info.fShaderPrep ? info.fShaderPrep(info.fShaderSource) :
124     info.fShaderSource;
125
126   wtu.addShaderSource(consoleDiv, fLabel, fSource);
127
128   // Reuse identical shaders so we test shared shader.
129   var fShader = fShaderDB[fSource];
130   if (!fShader) {
131     fShader = wtu.loadShader(gl, fSource, gl.FRAGMENT_SHADER);
132     if (info.fShaderTest) {
133       if (!info.fShaderTest(fShader)) {
134         testFailed("[fragment shader test] " + passMsg);
135         return;
136       }
137     }
138     //debug(fShader == null ? "fail" : "succeed");
139     // As per GLSL 1.0.17 10.27 we can only check for success on
140     // compileShader, not failure.
141     if (!info.ignoreResults && info.fShaderSuccess && !fShader) {
142       testFailed("[unexpected fragment shader compile status] (expected: " +
143                 info.fShaderSuccess + ") " + passMsg);
144       return;
145     }
146     // Safe the shaders so we test shared shader.
147     if (fShader) {
148       fShaderDB[fSource] = fShader;
149     }
150   }
151
152   if (debugShaders && fShader) {
153     wtu.addShaderSource(consoleDiv, fLabel + " translated for driver",
154                         debugShaders.getTranslatedShaderSource(fShader));
155   }
156
157   if (vShader && fShader) {
158     var program = gl.createProgram();
159     gl.attachShader(program, vShader);
160     gl.attachShader(program, fShader);
161
162     if (vSource.indexOf("vPosition") >= 0) {
163       gl.bindAttribLocation(program, 0, "vPosition");
164     }
165     if (vSource.indexOf("texCoord0") >= 0) {
166       gl.bindAttribLocation(program, 1, "texCoord0");
167     }
168     gl.linkProgram(program);
169     var linked = (gl.getProgramParameter(program, gl.LINK_STATUS) != 0);
170     if (!linked) {
171       var error = gl.getProgramInfoLog(program);
172       log("*** Error linking program '"+program+"':"+error);
173     }
174     if (!info.ignoreResults && linked != info.linkSuccess) {
175       testFailed("[unexpected link status] " + passMsg);
176       return;
177     }
178   } else {
179     if (!info.ignoreResults && info.linkSuccess) {
180       testFailed("[link failed] " + passMsg);
181       return;
182     }
183   }
184
185   if (!info.render) {
186     testPassed(passMsg);
187     return;
188   }
189
190   gl.useProgram(program);
191   wtu.setupUnitQuad(gl);
192   wtu.clearAndDrawUnitQuad(gl);
193
194   var div = document.createElement("div");
195   div.className = "testimages";
196   wtu.insertImage(div, "result", wtu.makeImage(gl.canvas));
197   div.appendChild(document.createElement('br'));
198   consoleDiv.appendChild(div);
199   wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green", 0);
200 }
201
202 function runTests(shaderInfos) {
203   var wtu = WebGLTestUtils;
204   var canvas = document.createElement('canvas');
205   canvas.width = 32;
206   canvas.height = 32;
207   var gl = wtu.create3DContext(canvas);
208   if (!gl) {
209     testFailed("context does not exist");
210     finishTest();
211     return;
212   }
213
214   var testIndex = 0;
215   var runNextTest = function() {
216     if (testIndex == shaderInfos.length) {
217       finishTest();
218       return;
219     }
220
221     runOneTest(gl, shaderInfos[testIndex++]);
222     setTimeout(runNextTest, 1);
223   }
224   runNextTest();
225 };
226
227 function loadExternalShaders(filename, passMsg) {
228   var shaderInfos = [];
229   var lines = wtu.readFileList(filename);
230   for (var ii = 0; ii < lines.length; ++ii) {
231     var info = {
232       vShaderSource:  defaultVertexShader,
233       vShaderSuccess: true,
234       fShaderSource:  defaultFragmentShader,
235       fShaderSuccess: true,
236       linkSuccess:    true,
237     };
238
239     var line = lines[ii];
240     var files = line.split(/ +/);
241     var passMsg = "";
242     for (var jj = 0; jj < files.length; ++jj) {
243       var file = files[jj];
244       var shaderSource = wtu.readFile(file);
245       var firstLine = shaderSource.split("\n")[0];
246       var success = undefined;
247       if (firstLine.indexOf("fail") >= 0) {
248         success = false;
249       } else if (firstLine.indexOf("succeed") >= 0) {
250         success = true;
251       }
252       if (success === undefined) {
253         testFailed("bad first line in " + file + ":" + firstLine);
254         continue;
255       }
256       if (!wtu.startsWith(firstLine, "// ")) {
257         testFailed("bad first line in " + file + ":" + firstLine);
258         continue;
259       }
260       passMsg = passMsg + (passMsg.length ? ", " : "") + firstLine.substr(3);
261       if (wtu.endsWith(file, ".vert")) {
262         info.vShaderSource = shaderSource;
263         info.vShaderSuccess = success;
264       } else if (wtu.endsWith(file, ".frag")) {
265         info.fShaderSource = shaderSource;
266         info.fShaderSuccess = success;
267       }
268     }
269     info.linkSuccess = info.vShaderSuccess && info.fShaderSuccess;
270     info.passMsg = passMsg;
271     shaderInfos.push(info);
272   }
273   return shaderInfos;
274 }
275
276 function getSource(elem) {
277   var str = elem.text;
278   return str.replace(/^\s*/, '').replace(/\s*$/, '');
279 }
280
281 function getPassMessage(source) {
282   var lines = source.split('\n');
283   return lines[0].substring(3);
284 }
285
286 function getSuccess(msg) {
287   if (msg.indexOf("fail") >= 0) {
288     return false;
289   }
290   if (msg.indexOf("succeed") >= 0) {
291     return true;
292   }
293   testFailed("bad test description. Must have 'fail' or 'succeed'");
294 }
295
296 function setupTest() {
297   var vShaderElem = document.getElementById('vertexShader');
298   var vShaderSource = defaultVertexShader;
299   var vShaderSuccess = true;
300
301   var fShaderElem = document.getElementById('fragmentShader');
302   var fShaderSource = defaultFragmentShader;
303   var fShaderSuccess = true;
304
305   var passMsg = undefined;
306
307   if (vShaderElem) {
308     vShaderSource = getSource(vShaderElem);
309     passMsg = getPassMessage(vShaderSource);
310     vShaderSuccess = getSuccess(passMsg);
311   }
312
313   if (fShaderElem) {
314     fShaderSource = getSource(fShaderElem);
315     passMsg = getPassMessage(fShaderSource);
316     fShaderSuccess = getSuccess(passMsg);
317   }
318
319   var linkSuccess = vShaderSuccess && fShaderSuccess;
320
321   if (passMsg === undefined) {
322     testFailed("no test shader found.");
323     finishTest();
324     return;
325   }
326
327   var info = {
328     vShaderSource: vShaderSource,
329     vShaderSuccess: vShaderSuccess,
330     fShaderSource: fShaderSource,
331     fShaderSuccess: fShaderSuccess,
332     linkSuccess: linkSuccess,
333     passMsg: passMsg
334   };
335
336   return info;
337 }
338
339 function runTest() {
340   var info = setupTest();
341   description(info.passMsg);
342   runTests([info]);
343 }
344
345 function runRenderTests(tests) {
346   for (var ii = 0; ii < tests.length; ++ii) {
347     tests[ii].render = true
348   }
349   runTests(tests);
350 }
351
352 function runRenderTest() {
353   var info = setupTest();
354   description(info.passMsg);
355   runRenderTests([info]);
356 }
357
358 return {
359   runTest: runTest,
360   runTests: runTests,
361   runRenderTest: runRenderTest,
362   runRenderTests: runRenderTests,
363   loadExternalShaders: loadExternalShaders,
364
365   none: false,
366 };
367 }());