test_pixel_pack_buffer.html (7168B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset='UTF-8'> 5 <script src='/tests/SimpleTest/SimpleTest.js'></script> 6 <link rel='stylesheet' href='/tests/SimpleTest/test.css'> 7 </head> 8 <body> 9 <script> 10 11 var RED = [1, 0, 0, 1]; 12 var GREEN = [0, 1, 0, 1]; 13 var BLUE = [0, 0, 1, 1]; 14 var WHITE = [1, 1, 1, 1]; 15 var ZERO = [0, 0, 0, 0]; 16 17 function DrawColors(gl) { 18 var fnClearToColor = function(color) { 19 gl.clearColor(color[0], color[1], color[2], color[3]); 20 gl.clear(gl.COLOR_BUFFER_BIT); 21 }; 22 23 gl.enable(gl.SCISSOR_TEST); 24 25 // +---+ 26 // |G W| 27 // |R B| 28 // +---+ 29 30 gl.scissor(0, 0, 1, 1); 31 fnClearToColor(RED); 32 33 gl.scissor(1, 0, 1, 1); 34 fnClearToColor(BLUE); 35 36 gl.scissor(0, 1, 1, 1); 37 fnClearToColor(GREEN); 38 39 gl.scissor(1, 1, 1, 1); 40 fnClearToColor(WHITE); 41 } 42 43 function ClearBufferPair(gl, byteCount) { 44 // Using `null` here clears to zero according to WebGL. 45 gl.bufferData(gl.PIXEL_PACK_BUFFER, byteCount, gl.STREAM_READ); 46 47 var arr = new Uint8Array(byteCount); 48 return arr; 49 } 50 51 function ColorToString(color, offset=0) { 52 var arr = [ color[offset+0], 53 color[offset+1], 54 color[offset+2], 55 color[offset+3] ]; 56 return '[' + arr.join(', ') + ']'; 57 } 58 59 function TestIsUNormColor(refColor, testData, offset) { 60 if (testData.length < offset + 4) { 61 ok(false, 'testData not long enough.'); 62 } 63 64 var refUNormColor = [ 65 (refColor[0] * 255) | 0, 66 (refColor[1] * 255) | 0, 67 (refColor[2] * 255) | 0, 68 (refColor[3] * 255) | 0, 69 ]; 70 71 var refStr = ColorToString(refUNormColor); 72 var testStr = ColorToString(testData, offset); 73 ok(testStr == refStr, 'Expected ' + refStr + ', was ' + testStr + '.'); 74 } 75 76 function section(text) { 77 ok(true, ''); 78 ok(true, 'Section: ' + text); 79 } 80 81 function EnsureNoError(gl) { 82 var glErr = gl.getError(); 83 while (gl.getError()) {} 84 85 if (!glErr) 86 return; 87 88 var extraInfo = ''; 89 90 var err = new Error(); 91 var stackStr = err.stack; 92 if (stackStr !== undefined) { 93 var stackArr = stackStr.split('\n'); 94 stackStr = stackArr[1]; // First one after present scope. 95 extraInfo = ': ' + stackStr; 96 } 97 98 ok(false, 'Unexpected GL error: 0x' + glErr.toString(16) + extraInfo); 99 } 100 101 function TestError(gl, refErrVal, str='') { 102 if (str == '') { 103 str = 'gl.getError()'; 104 } else { 105 str = str + ': gl.getError()'; 106 } 107 108 var err = gl.getError(); 109 while (gl.getError()) {} 110 111 ShouldBe(err.toString(16), refErrVal.toString(16), str); 112 } 113 114 function ShouldBe(val, ref, str='') { 115 if (str != '') { 116 str += ': '; 117 } 118 119 ok(val == ref, str + 'Should be `' + ref + '`, was `' + val + '`.'); 120 } 121 122 var gl; 123 124 function Test() { 125 var canvas = document.createElement('canvas'); 126 canvas.width = 2; 127 canvas.height = 2; 128 canvas.style = 'width: 256px; height: 256px; border: 1px solid black;'; 129 document.body.appendChild(canvas); 130 131 var attribs = { 132 antialias: false, 133 alpha: false, 134 }; 135 gl = canvas.getContext('webgl2', attribs); 136 if (!gl) { 137 todo(false, 'WebGL 2 not present, skipping.'); 138 return; 139 } 140 141 //////// 142 143 TestIsUNormColor(RED, new Uint8Array([255, 0, 0, 255]), 0); 144 145 //////// 146 147 gl.clearColor(RED[0], RED[1], RED[2], RED[3]); 148 gl.clear(gl.COLOR_BUFFER_BIT); 149 150 var data = new Uint8Array(16); 151 gl.readPixels(0, 0, 2, 2, gl.RGBA, gl.UNSIGNED_BYTE, data); 152 console.log(JSON.stringify(data)); 153 TestIsUNormColor(RED, data, 0); 154 155 //////// 156 157 DrawColors(gl); 158 159 //////// 160 161 EnsureNoError(gl); 162 gl.readPixels(0, 0, 2, 2, gl.RGBA, gl.UNSIGNED_BYTE, 0); 163 TestError(gl, gl.INVALID_OPERATION); 164 165 var data = new Uint8Array(16); 166 gl.readPixels(0, 0, 2, 2, gl.RGBA, gl.UNSIGNED_BYTE, data); 167 EnsureNoError(gl); 168 TestIsUNormColor(RED, data, 0); 169 TestIsUNormColor(BLUE, data, 4); 170 TestIsUNormColor(GREEN, data, 8); 171 TestIsUNormColor(WHITE, data, 12); 172 173 //////// 174 175 var a = gl.createBuffer(); 176 gl.bindBuffer(gl.PIXEL_PACK_BUFFER, a); 177 EnsureNoError(gl); 178 179 gl.readPixels(0, 0, 2, 2, gl.RGBA, gl.UNSIGNED_BYTE, data); 180 TestError(gl, gl.INVALID_OPERATION); 181 182 //////// 183 184 // Basic 185 section('Basic readback'); 186 data = ClearBufferPair(gl, 16); 187 EnsureNoError(gl); 188 gl.readPixels(0, 0, 2, 2, gl.RGBA, gl.UNSIGNED_BYTE, 0); 189 EnsureNoError(gl); 190 gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, data); 191 EnsureNoError(gl); 192 TestIsUNormColor(RED, data, 0); 193 TestIsUNormColor(BLUE, data, 4); 194 TestIsUNormColor(GREEN, data, 8); 195 TestIsUNormColor(WHITE, data, 12); 196 197 section('Subrect readback'); 198 data = ClearBufferPair(gl, 8); 199 gl.readPixels(1, 1, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, 0); 200 gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, data); 201 EnsureNoError(gl); 202 TestIsUNormColor(WHITE, data, 0); 203 TestIsUNormColor(ZERO, data, 4); 204 205 section('ReadPixels offset:4'); 206 data = ClearBufferPair(gl, 16); 207 gl.readPixels(1, 1, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, 4); 208 gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, data); 209 EnsureNoError(gl); 210 TestIsUNormColor(ZERO, data, 0); 211 TestIsUNormColor(WHITE, data, 4); 212 TestIsUNormColor(ZERO, data, 8); 213 TestIsUNormColor(ZERO, data, 12); 214 215 section('ReadPixels offset:5'); 216 gl.readPixels(1, 1, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, 5); 217 gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, data); 218 EnsureNoError(gl); 219 TestIsUNormColor(ZERO, data, 0); 220 TestIsUNormColor(WHITE, data, 4); // Should remain from previous read. 221 TestIsUNormColor(WHITE, data, 5); 222 TestIsUNormColor(ZERO, data, 9); 223 TestIsUNormColor(ZERO, data, 12); 224 225 section('GetBufferSubData src too small'); 226 data = ClearBufferPair(gl, 16); 227 EnsureNoError(gl); 228 gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 1, data); 229 TestError(gl, gl.INVALID_VALUE); 230 TestIsUNormColor(ZERO, data, 0); 231 TestIsUNormColor(ZERO, data, 4); 232 TestIsUNormColor(ZERO, data, 8); 233 TestIsUNormColor(ZERO, data, 12); 234 235 section('GetBufferSubData offset:1'); 236 data = new Uint8Array(15); 237 gl.readPixels(1, 1, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, 8); 238 gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 1, data); 239 EnsureNoError(gl); 240 TestIsUNormColor(ZERO, data, 0); 241 TestIsUNormColor(ZERO, data, 3); 242 TestIsUNormColor(WHITE, data, 7); 243 TestIsUNormColor(ZERO, data, 11); 244 245 ////////////////////////////////////// 246 247 section('Test packing state'); 248 EnsureNoError(gl); 249 250 function TestPackState(enumStr, initialVal, changedVal) { 251 var enumVal = gl[enumStr]; 252 253 ShouldBe(gl.getParameter(enumVal), initialVal, 'Initial ' + enumStr); 254 gl.pixelStorei(enumVal, changedVal); 255 ShouldBe(gl.getParameter(enumVal), changedVal, 'Changed ' + enumStr); 256 gl.pixelStorei(enumVal, initialVal); 257 ShouldBe(gl.getParameter(enumVal), initialVal, 'Reverted ' + enumStr); 258 EnsureNoError(gl); 259 } 260 261 TestPackState('PACK_ALIGNMENT', 4, 1); 262 TestPackState('PACK_ROW_LENGTH', 0, 16); 263 TestPackState('PACK_SKIP_PIXELS', 0, 3); 264 TestPackState('PACK_SKIP_ROWS', 0, 3); 265 } 266 267 function RunTest() { 268 Test(); 269 SimpleTest.finish(); 270 } 271 272 SimpleTest.waitForExplicitFinish(); 273 274 try { 275 var prefArrArr = [ 276 ['webgl.force-enabled', true], 277 ['webgl.disable-angle', true], 278 ]; 279 var prefEnv = {'set': prefArrArr}; 280 SpecialPowers.pushPrefEnv(prefEnv, RunTest); 281 } catch (e) { 282 todo(false, 'No SpecialPowers, but trying anyway...'); 283 RunTest(); 284 } 285 286 </script> 287 </body> 288 </html>