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 | <!DOCTYPE HTML> |
michael@0 | 2 | <title>WebGL test: Drawing without attrib arrays</title> |
michael@0 | 3 | <script src="/tests/SimpleTest/SimpleTest.js"></script> |
michael@0 | 4 | <link rel="stylesheet" href="/tests/SimpleTest/test.css"> |
michael@0 | 5 | <script src="driver-info.js"></script> |
michael@0 | 6 | <script src="webgl-util.js"></script> |
michael@0 | 7 | <script id="vs-no-attrib" type="x-shader/x-vertex"> |
michael@0 | 8 | |
michael@0 | 9 | void main(void) { |
michael@0 | 10 | gl_PointSize = 64.0; |
michael@0 | 11 | gl_Position = vec4(vec3(0.0), 1.0); |
michael@0 | 12 | } |
michael@0 | 13 | |
michael@0 | 14 | </script> |
michael@0 | 15 | <script id="vs-attrib" type="x-shader/x-vertex"> |
michael@0 | 16 | |
michael@0 | 17 | attribute vec3 aPosition; |
michael@0 | 18 | |
michael@0 | 19 | void main(void) { |
michael@0 | 20 | gl_PointSize = 64.0; |
michael@0 | 21 | gl_Position = vec4(aPosition, 1.0); |
michael@0 | 22 | } |
michael@0 | 23 | |
michael@0 | 24 | </script> |
michael@0 | 25 | <script id="fs" type="x-shader/x-fragment"> |
michael@0 | 26 | |
michael@0 | 27 | precision mediump float; |
michael@0 | 28 | |
michael@0 | 29 | void main(void) { |
michael@0 | 30 | gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); |
michael@0 | 31 | } |
michael@0 | 32 | |
michael@0 | 33 | </script> |
michael@0 | 34 | <body> |
michael@0 | 35 | <canvas id="c" width="64" height="64"></canvas> |
michael@0 | 36 | <script> |
michael@0 | 37 | |
michael@0 | 38 | // Give ourselves a scope to return early from: |
michael@0 | 39 | (function() { |
michael@0 | 40 | var gl = WebGLUtil.getWebGL('c'); |
michael@0 | 41 | if (!gl) { |
michael@0 | 42 | todo(false, 'WebGL is unavailable.'); |
michael@0 | 43 | return; |
michael@0 | 44 | } |
michael@0 | 45 | |
michael@0 | 46 | function errorFunc(str) { |
michael@0 | 47 | ok(false, 'Error: ' + str); |
michael@0 | 48 | } |
michael@0 | 49 | WebGLUtil.setErrorFunc(errorFunc); |
michael@0 | 50 | WebGLUtil.setWarningFunc(errorFunc); |
michael@0 | 51 | |
michael@0 | 52 | var attribProg = WebGLUtil.createProgramByIds(gl, 'vs-attrib', 'fs'); |
michael@0 | 53 | var noAttribProg = WebGLUtil.createProgramByIds(gl, 'vs-no-attrib', 'fs'); |
michael@0 | 54 | if (!attribProg || !noAttribProg) { |
michael@0 | 55 | ok(false, 'Program linking should succeed.'); |
michael@0 | 56 | return; |
michael@0 | 57 | } |
michael@0 | 58 | |
michael@0 | 59 | attribProg.aPosition = gl.getAttribLocation(attribProg, "aPosition"); |
michael@0 | 60 | ok(attribProg.aPosition >= 0, '`aPosition` should be valid.'); |
michael@0 | 61 | |
michael@0 | 62 | function isScreenBlack() { |
michael@0 | 63 | var pixels = gl.drawingBufferWidth * gl.drawingBufferHeight; |
michael@0 | 64 | var data = new Uint8Array(4 * pixels); |
michael@0 | 65 | gl.readPixels(0, 0, |
michael@0 | 66 | gl.drawingBufferWidth, gl.drawingBufferHeight, |
michael@0 | 67 | gl.RGBA, gl.UNSIGNED_BYTE, |
michael@0 | 68 | data); |
michael@0 | 69 | |
michael@0 | 70 | var accum = 0; |
michael@0 | 71 | for (var i = 0; i < pixels; i++) { |
michael@0 | 72 | accum += data[4*i + 0]; |
michael@0 | 73 | accum += data[4*i + 1]; |
michael@0 | 74 | accum += data[4*i + 2]; |
michael@0 | 75 | } |
michael@0 | 76 | |
michael@0 | 77 | return accum == 0; |
michael@0 | 78 | } |
michael@0 | 79 | |
michael@0 | 80 | function checkGLError(func, info) { |
michael@0 | 81 | var error = gl.getError(); |
michael@0 | 82 | func(!error, '[' + info + '] gl.getError should be 0, was 0x' + error.toString(16) + '.'); |
michael@0 | 83 | } |
michael@0 | 84 | |
michael@0 | 85 | function testDrawing(info) { |
michael@0 | 86 | var cruelNumber = 1024*1024; |
michael@0 | 87 | // Really, we should test for INT32_MAX-1 here, but we don't gracefully chunk these calls, |
michael@0 | 88 | // and so try to create a VBO of size INT32_MAX-1 to pretend that vert attrib 0 is an array. |
michael@0 | 89 | // (INT32_MAX-1 because we check that `first+count` is a valid GLsizei, which is int32_t) |
michael@0 | 90 | var UINT16_MAX = 0xffff; |
michael@0 | 91 | var INT32_MAX = 0x7fffffff; |
michael@0 | 92 | var UINT32_MAX = 0xffffffff; |
michael@0 | 93 | |
michael@0 | 94 | // `first` needs room for `first+count` <= sizeof(GLsizei) == INT32_MAX |
michael@0 | 95 | var hugeFirst = Math.min(cruelNumber, INT32_MAX-1); |
michael@0 | 96 | var hugeIndex = Math.min(cruelNumber, UINT32_MAX); |
michael@0 | 97 | |
michael@0 | 98 | var indexType = gl.UNSIGNED_SHORT; |
michael@0 | 99 | var indexStride = 2; |
michael@0 | 100 | var indexArr = new Uint16Array([0, 1, Math.min(hugeIndex, UINT16_MAX)]); |
michael@0 | 101 | if (gl.getExtension('OES_element_index_uint')) { |
michael@0 | 102 | indexType = gl.UNSIGNED_INT; |
michael@0 | 103 | indexStride = 4; |
michael@0 | 104 | indexArr = new Uint32Array([0, 1, hugeIndex]); |
michael@0 | 105 | } |
michael@0 | 106 | |
michael@0 | 107 | gl.clear(gl.COLOR_BUFFER_BIT); |
michael@0 | 108 | gl.drawArrays(gl.POINTS, 0, 1); |
michael@0 | 109 | ok(!isScreenBlack(), '[' + info + '] drawArrays should color pixels.'); |
michael@0 | 110 | |
michael@0 | 111 | gl.clear(gl.COLOR_BUFFER_BIT); |
michael@0 | 112 | gl.drawArrays(gl.POINTS, hugeFirst, 1); |
michael@0 | 113 | ok(!isScreenBlack(), '[' + info + '] drawArrays[huge first] should color pixels.'); |
michael@0 | 114 | |
michael@0 | 115 | checkGLError(ok, info); |
michael@0 | 116 | |
michael@0 | 117 | var elemTestFunc = todo; // We fail on most implementations. |
michael@0 | 118 | var checkGLTestFunc = todo; |
michael@0 | 119 | if (DriverInfo.getDriver() == DriverInfo.DRIVER.ANGLE || |
michael@0 | 120 | DriverInfo.getOS() == DriverInfo.OS.ANDROID) |
michael@0 | 121 | { |
michael@0 | 122 | // ANGLE and Android slaves seem to work fine. |
michael@0 | 123 | elemTestFunc = ok; |
michael@0 | 124 | checkGLTestFunc = ok; |
michael@0 | 125 | } |
michael@0 | 126 | if (DriverInfo.getDriver() == DriverInfo.DRIVER.ANDROID_X86_EMULATOR || |
michael@0 | 127 | DriverInfo.getOS() == DriverInfo.OS.B2G) |
michael@0 | 128 | { |
michael@0 | 129 | // ...but the Android 4.2 x86 emulator environment is different |
michael@0 | 130 | elemTestFunc = todo; |
michael@0 | 131 | checkGLTestFunc = ok; |
michael@0 | 132 | } |
michael@0 | 133 | |
michael@0 | 134 | // Now for drawElements: |
michael@0 | 135 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer()); |
michael@0 | 136 | gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexArr, gl.STATIC_DRAW); |
michael@0 | 137 | |
michael@0 | 138 | gl.clear(gl.COLOR_BUFFER_BIT); |
michael@0 | 139 | gl.drawElements(gl.POINTS, 1, indexType, 0); |
michael@0 | 140 | elemTestFunc(!isScreenBlack(), '[' + info + '] drawElements[0] should color pixels.'); |
michael@0 | 141 | |
michael@0 | 142 | gl.clear(gl.COLOR_BUFFER_BIT); |
michael@0 | 143 | gl.drawElements(gl.POINTS, 1, indexType, 1*indexStride); |
michael@0 | 144 | elemTestFunc(!isScreenBlack(), '[' + info + '] drawElements[1] should color pixels.'); |
michael@0 | 145 | |
michael@0 | 146 | gl.clear(gl.COLOR_BUFFER_BIT); |
michael@0 | 147 | gl.drawElements(gl.POINTS, 1, indexType, 2*indexStride); |
michael@0 | 148 | elemTestFunc(!isScreenBlack(), '[' + info + '] drawElements[huge offset] should color pixels.'); |
michael@0 | 149 | |
michael@0 | 150 | checkGLError(checkGLTestFunc, info); |
michael@0 | 151 | } |
michael@0 | 152 | |
michael@0 | 153 | // Begin drawing |
michael@0 | 154 | gl.clearColor(0.0, 0.0, 0.0, 1.0); |
michael@0 | 155 | gl.disable(gl.DEPTH_TEST); |
michael@0 | 156 | |
michael@0 | 157 | // No-attrib prog: |
michael@0 | 158 | gl.useProgram(noAttribProg); |
michael@0 | 159 | testDrawing('no-attrib'); |
michael@0 | 160 | |
michael@0 | 161 | // One-attrib, no-array prog: |
michael@0 | 162 | gl.useProgram(attribProg); |
michael@0 | 163 | gl.disableVertexAttribArray(attribProg.aPosition); |
michael@0 | 164 | gl.vertexAttrib3fv(attribProg.aPosition, [0.0, 0.0, 0.0]); |
michael@0 | 165 | testDrawing('one-attrib, no-array'); |
michael@0 | 166 | })(); |
michael@0 | 167 | |
michael@0 | 168 | </script> |
michael@0 | 169 |