Upstream version 11.40.277.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
147     // Safe the shaders so we test shared shader.
148     if (fShader) {
149       fShaderDB[fSource] = fShader;
150     }
151   }
152
153   if (debugShaders && fShader) {
154     wtu.addShaderSource(consoleDiv, fLabel + " translated for driver",
155                         debugShaders.getTranslatedShaderSource(fShader));
156   }
157
158   if (vShader && fShader) {
159     var program = gl.createProgram();
160     gl.attachShader(program, vShader);
161     gl.attachShader(program, fShader);
162
163     if (vSource.indexOf("vPosition") >= 0) {
164       gl.bindAttribLocation(program, 0, "vPosition");
165     }
166     if (vSource.indexOf("texCoord0") >= 0) {
167       gl.bindAttribLocation(program, 1, "texCoord0");
168     }
169     gl.linkProgram(program);
170     var linked = (gl.getProgramParameter(program, gl.LINK_STATUS) != 0);
171     if (!linked) {
172       var error = gl.getProgramInfoLog(program);
173       log("*** Error linking program '"+program+"':"+error);
174     }
175     if (!info.ignoreResults && linked != info.linkSuccess) {
176       testFailed("[unexpected link status] " + passMsg);
177       return;
178     }
179   } else {
180     if (!info.ignoreResults && info.linkSuccess) {
181       testFailed("[link failed] " + passMsg);
182       return;
183     }
184   }
185
186   if (parseInt(wtu.getUrlOptions().dumpShaders)) {
187     var vInfo = {
188       shader: vShader,
189       shaderSuccess: info.vShaderSuccess,
190       label: vLabel,
191       source: vSource
192     };
193     var fInfo = {
194       shader: fShader,
195       shaderSuccess: info.fShaderSuccess,
196       label: fLabel,
197       source: fSource
198     };
199     wtu.dumpShadersInfo(gl, window.location.pathname, passMsg, vInfo, fInfo);
200   }
201
202   if (!info.render) {
203     testPassed(passMsg);
204     return;
205   }
206
207   gl.useProgram(program);
208   wtu.setupUnitQuad(gl);
209   wtu.clearAndDrawUnitQuad(gl);
210
211   var div = document.createElement("div");
212   div.className = "testimages";
213   wtu.insertImage(div, "result", wtu.makeImageFromCanvas(gl.canvas));
214   div.appendChild(document.createElement('br'));
215   consoleDiv.appendChild(div);
216   wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green", 0);
217 }
218
219 function runTests(shaderInfos) {
220   var wtu = WebGLTestUtils;
221   var canvas = document.createElement('canvas');
222   canvas.width = 32;
223   canvas.height = 32;
224   var gl = wtu.create3DContext(canvas);
225   if (!gl) {
226     testFailed("context does not exist");
227     finishTest();
228     return;
229   }
230
231   var testIndex = 0;
232   var runNextTest = function() {
233     if (testIndex == shaderInfos.length) {
234       finishTest();
235       return;
236     }
237
238     runOneTest(gl, shaderInfos[testIndex++]);
239     setTimeout(runNextTest, 1);
240   }
241   runNextTest();
242 };
243
244 function loadExternalShaders(filename, passMsg) {
245   var shaderInfos = [];
246   var lines = wtu.readFileList(filename);
247   for (var ii = 0; ii < lines.length; ++ii) {
248     var info = {
249       vShaderSource:  defaultVertexShader,
250       vShaderSuccess: true,
251       fShaderSource:  defaultFragmentShader,
252       fShaderSuccess: true,
253       linkSuccess:    true,
254     };
255
256     var line = lines[ii];
257     var files = line.split(/ +/);
258     var passMsg = "";
259     for (var jj = 0; jj < files.length; ++jj) {
260       var file = files[jj];
261       var shaderSource = wtu.readFile(file);
262       var firstLine = shaderSource.split("\n")[0];
263       var success = undefined;
264       if (firstLine.indexOf("fail") >= 0) {
265         success = false;
266       } else if (firstLine.indexOf("succeed") >= 0) {
267         success = true;
268       }
269       if (success === undefined) {
270         testFailed("bad first line in " + file + ":" + firstLine);
271         continue;
272       }
273       if (!wtu.startsWith(firstLine, "// ")) {
274         testFailed("bad first line in " + file + ":" + firstLine);
275         continue;
276       }
277       passMsg = passMsg + (passMsg.length ? ", " : "") + firstLine.substr(3);
278       if (wtu.endsWith(file, ".vert")) {
279         info.vShaderSource = shaderSource;
280         info.vShaderSuccess = success;
281       } else if (wtu.endsWith(file, ".frag")) {
282         info.fShaderSource = shaderSource;
283         info.fShaderSuccess = success;
284       }
285     }
286     info.linkSuccess = info.vShaderSuccess && info.fShaderSuccess;
287     info.passMsg = passMsg;
288     shaderInfos.push(info);
289   }
290   return shaderInfos;
291 }
292
293 function getSource(elem) {
294   var str = elem.text;
295   return str.replace(/^\s*/, '').replace(/\s*$/, '');
296 }
297
298 function getPassMessage(source) {
299   var lines = source.split('\n');
300   return lines[0].substring(3);
301 }
302
303 function getSuccess(msg) {
304   if (msg.indexOf("fail") >= 0) {
305     return false;
306   }
307   if (msg.indexOf("succeed") >= 0) {
308     return true;
309   }
310   testFailed("bad test description. Must have 'fail' or 'succeed'");
311 }
312
313 function setupTest() {
314   var vShaderElem = document.getElementById('vertexShader');
315   var vShaderSource = defaultVertexShader;
316   var vShaderSuccess = true;
317
318   var fShaderElem = document.getElementById('fragmentShader');
319   var fShaderSource = defaultFragmentShader;
320   var fShaderSuccess = true;
321
322   var passMsg = undefined;
323
324   if (vShaderElem) {
325     vShaderSource = getSource(vShaderElem);
326     passMsg = getPassMessage(vShaderSource);
327     vShaderSuccess = getSuccess(passMsg);
328   }
329
330   if (fShaderElem) {
331     fShaderSource = getSource(fShaderElem);
332     passMsg = getPassMessage(fShaderSource);
333     fShaderSuccess = getSuccess(passMsg);
334   }
335
336   var linkSuccess = vShaderSuccess && fShaderSuccess;
337
338   if (passMsg === undefined) {
339     testFailed("no test shader found.");
340     finishTest();
341     return;
342   }
343
344   var info = {
345     vShaderSource: vShaderSource,
346     vShaderSuccess: vShaderSuccess,
347     fShaderSource: fShaderSource,
348     fShaderSuccess: fShaderSuccess,
349     linkSuccess: linkSuccess,
350     passMsg: passMsg
351   };
352
353   return info;
354 }
355
356 function runTest() {
357   var info = setupTest();
358   description(info.passMsg);
359   runTests([info]);
360 }
361
362 function runRenderTests(tests) {
363   for (var ii = 0; ii < tests.length; ++ii) {
364     tests[ii].render = true
365   }
366   runTests(tests);
367 }
368
369 function runRenderTest() {
370   var info = setupTest();
371   description(info.passMsg);
372   runRenderTests([info]);
373 }
374
375 return {
376   runTest: runTest,
377   runTests: runTests,
378   runRenderTest: runRenderTest,
379   runRenderTests: runRenderTests,
380   loadExternalShaders: loadExternalShaders,
381
382   none: false,
383 };
384 }());