diff --git a/dist/regl.js b/dist/regl.js index 105828eb..778bf96e 100644 --- a/dist/regl.js +++ b/dist/regl.js @@ -120,7 +120,8 @@ var constructorKeys = [ 'extensions', 'optionalExtensions', 'profile', - 'onDone' + 'onDone', + 'cachedCode' ] function checkConstructor (obj) { @@ -915,6 +916,7 @@ function parseArgs (args_) { var optionalExtensions = [] var pixelRatio = (typeof window === 'undefined' ? 1 : window.devicePixelRatio) var profile = false + var cachedCode = {} var onDone = function (err) { if (err) { check$1.raise(err) @@ -965,6 +967,12 @@ function parseArgs (args_) { pixelRatio = +args.pixelRatio check$1(pixelRatio > 0, 'invalid pixel ratio') } + if ('cachedCode' in args) { + check$1.type( + args.cachedCode, 'object', + 'invalid cachedCode') + cachedCode = args.cachedCode + } } } else { check$1.raise('invalid arguments to regl') @@ -1009,6 +1017,7 @@ function parseArgs (args_) { optionalExtensions: optionalExtensions, pixelRatio: pixelRatio, profile: profile, + cachedCode: cachedCode, onDone: onDone, onDestroy: onDestroy } @@ -5575,16 +5584,13 @@ function wrapShaderState (gl, stringStore, stats, config) { gl.getUniformLocation(program, name), info)) } + } else { + insertActiveInfo(uniforms, new ActiveInfo( + info.name, + stringStore.id(info.name), + gl.getUniformLocation(program, info.name), + info)) } - var uniName = info.name - if (info.size > 1) { - uniName = uniName.replace('[0]', '') - } - insertActiveInfo(uniforms, new ActiveInfo( - uniName, - stringStore.id(uniName), - gl.getUniformLocation(program, uniName), - info)) } } @@ -5849,6 +5855,298 @@ function wrapReadPixels ( return readPixels } +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined + * in FIPS 180-2 + * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for details. + * Also http://anmar.eu.org/projects/jssha2/ + */ + +/* + * Configurable variables. You may need to tweak these to be compatible with + * the server-side, but the defaults work in most cases. + */ +var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ +var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ + +/* + * These are the functions you'll usually want to call + * They take string arguments and return either hex or base-64 encoded strings + */ +function hex_sha256(s) { return rstr2hex(rstr_sha256(str2rstr_utf8(s))); } +/* + * Calculate the sha256 of a raw string + */ +function rstr_sha256(s) +{ + return binb2rstr(binb_sha256(rstr2binb(s), s.length * 8)); +} + +/* + * Calculate the HMAC-sha256 of a key and some data (raw strings) + */ +function rstr_hmac_sha256(key, data) +{ + var bkey = rstr2binb(key); + if(bkey.length > 16) bkey = binb_sha256(bkey, key.length * 8); + + var ipad = Array(16), opad = Array(16); + for(var i = 0; i < 16; i++) + { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = binb_sha256(ipad.concat(rstr2binb(data)), 512 + data.length * 8); + return binb2rstr(binb_sha256(opad.concat(hash), 512 + 256)); +} + +/* + * Convert a raw string to a hex string + */ +function rstr2hex(input) +{ + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var output = ""; + var x; + for(var i = 0; i < input.length; i++) + { + x = input.charCodeAt(i); + output += hex_tab.charAt((x >>> 4) & 0x0F) + + hex_tab.charAt( x & 0x0F); + } + return output; +} + +/* + * Convert a raw string to a base-64 string + */ +function rstr2b64(input) +{ + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var output = ""; + var len = input.length; + for(var i = 0; i < len; i += 3) + { + var triplet = (input.charCodeAt(i) << 16) + | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0) + | (i + 2 < len ? input.charCodeAt(i+2) : 0); + for(var j = 0; j < 4; j++) + { + if(i * 8 + j * 6 > input.length * 8) output += b64pad; + else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F); + } + } + return output; +} + +/* + * Convert a raw string to an arbitrary string encoding + */ +function rstr2any(input, encoding) +{ + var divisor = encoding.length; + var remainders = Array(); + var i, q, x, quotient; + + /* Convert to an array of 16-bit big-endian values, forming the dividend */ + var dividend = Array(Math.ceil(input.length / 2)); + for(i = 0; i < dividend.length; i++) + { + dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); + } + + /* + * Repeatedly perform a long division. The binary array forms the dividend, + * the length of the encoding is the divisor. Once computed, the quotient + * forms the dividend for the next step. We stop when the dividend is zero. + * All remainders are stored for later use. + */ + while(dividend.length > 0) + { + quotient = Array(); + x = 0; + for(i = 0; i < dividend.length; i++) + { + x = (x << 16) + dividend[i]; + q = Math.floor(x / divisor); + x -= q * divisor; + if(quotient.length > 0 || q > 0) + quotient[quotient.length] = q; + } + remainders[remainders.length] = x; + dividend = quotient; + } + + /* Convert the remainders to the output string */ + var output = ""; + for(i = remainders.length - 1; i >= 0; i--) + output += encoding.charAt(remainders[i]); + + /* Append leading zero equivalents */ + var full_length = Math.ceil(input.length * 8 / + (Math.log(encoding.length) / Math.log(2))) + for(i = output.length; i < full_length; i++) + output = encoding[0] + output; + + return output; +} + +/* + * Encode a string as utf-8. + * For efficiency, this assumes the input is valid utf-16. + */ +function str2rstr_utf8(input) +{ + var output = ""; + var i = -1; + var x, y; + + while(++i < input.length) + { + /* Decode utf-16 surrogate pairs */ + x = input.charCodeAt(i); + y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; + if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) + { + x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); + i++; + } + + /* Encode output as utf-8 */ + if(x <= 0x7F) + output += String.fromCharCode(x); + else if(x <= 0x7FF) + output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F), + 0x80 | ( x & 0x3F)); + else if(x <= 0xFFFF) + output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), + 0x80 | ((x >>> 6 ) & 0x3F), + 0x80 | ( x & 0x3F)); + else if(x <= 0x1FFFFF) + output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), + 0x80 | ((x >>> 12) & 0x3F), + 0x80 | ((x >>> 6 ) & 0x3F), + 0x80 | ( x & 0x3F)); + } + return output; +} + +/* + * Convert a raw string to an array of big-endian words + * Characters >255 have their high-byte silently ignored. + */ +function rstr2binb(input) +{ + var output = Array(input.length >> 2); + for(var i = 0; i < output.length; i++) + output[i] = 0; + for(var i = 0; i < input.length * 8; i += 8) + output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32); + return output; +} + +/* + * Convert an array of big-endian words to a string + */ +function binb2rstr(input) +{ + var output = ""; + for(var i = 0; i < input.length * 32; i += 8) + output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF); + return output; +} + +/* + * Main sha256 function, with its support functions + */ +function sha256_S (X, n) {return ( X >>> n ) | (X << (32 - n));} +function sha256_R (X, n) {return ( X >>> n );} +function sha256_Ch(x, y, z) {return ((x & y) ^ ((~x) & z));} +function sha256_Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));} +function sha256_Sigma0256(x) {return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));} +function sha256_Sigma1256(x) {return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));} +function sha256_Gamma0256(x) {return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));} +function sha256_Gamma1256(x) {return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));} +var sha256_K = new Array +( + 1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993, + -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987, + 1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522, + 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, + -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585, + 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, + 1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885, + -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344, + 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, + 1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872, + -1866530822, -1538233109, -1090935817, -965641998 +); + +function binb_sha256(m, l) +{ + var HASH = new Array(1779033703, -1150833019, 1013904242, -1521486534, + 1359893119, -1694144372, 528734635, 1541459225); + var W = new Array(64); + var a, b, c, d, e, f, g, h; + var i, j, T1, T2; + + /* append padding */ + m[l >> 5] |= 0x80 << (24 - l % 32); + m[((l + 64 >> 9) << 4) + 15] = l; + + for(i = 0; i < m.length; i += 16) + { + a = HASH[0]; + b = HASH[1]; + c = HASH[2]; + d = HASH[3]; + e = HASH[4]; + f = HASH[5]; + g = HASH[6]; + h = HASH[7]; + + for(j = 0; j < 64; j++) + { + if (j < 16) W[j] = m[j + i]; + else W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]), + sha256_Gamma0256(W[j - 15])), W[j - 16]); + + T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)), + sha256_K[j]), W[j]); + T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c)); + h = g; + g = f; + f = e; + e = safe_add(d, T1); + d = c; + c = b; + b = a; + a = safe_add(T1, T2); + } + + HASH[0] = safe_add(a, HASH[0]); + HASH[1] = safe_add(b, HASH[1]); + HASH[2] = safe_add(c, HASH[2]); + HASH[3] = safe_add(d, HASH[3]); + HASH[4] = safe_add(e, HASH[4]); + HASH[5] = safe_add(f, HASH[5]); + HASH[6] = safe_add(g, HASH[6]); + HASH[7] = safe_add(h, HASH[7]); + } + return HASH; +} + +function safe_add (x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + function slice (x) { return Array.prototype.slice.call(x) } @@ -5857,7 +6155,9 @@ function join (x) { return slice(x).join('') } -function createEnvironment () { +function createEnvironment (options) { + var cache = options && options.cache + // Unique variable id counter var varCounter = 0 @@ -5866,16 +6166,21 @@ function createEnvironment () { // the variable name which it is bound to var linkedNames = [] var linkedValues = [] - function link (value) { - for (var i = 0; i < linkedValues.length; ++i) { - if (linkedValues[i] === value) { - return linkedNames[i] + var isStable = [] + function link (value, options) { + var stable = options && options.stable + if (!stable) { + for (var i = 0; i < linkedValues.length; ++i) { + if (linkedValues[i] === value && !isStable[i]) { + return linkedNames[i] + } } } var name = 'g' + (varCounter++) linkedNames.push(name) linkedValues.push(value) + isStable.push(stable) return name } @@ -6015,7 +6320,21 @@ function createEnvironment () { .replace(/;/g, ';\n') .replace(/}/g, '}\n') .replace(/{/g, '{\n') + + var key + if (cache) { + key = hex_sha256(src); + + if (cache[key]) { + return cache[key].apply(null, linkedValues) + } + } + var proc = Function.apply(null, linkedNames.concat(src)) + + if (cache) { + cache[key] = proc + } return proc.apply(null, linkedValues) } @@ -6353,6 +6672,7 @@ function reglCore ( drawState, contextState, timer, + cachedCode, config) { var AttributeRecord = attributeState.Record @@ -6406,6 +6726,14 @@ function reglCore ( } GL_VARIABLES[name] = func } + + function hasVariableReference (exp) { + if (!isNaN(exp)) { + return false; + } + // strengthen this function if variable values can be non-(null/number) literals. + return true; + } // Dithering stateFlag(S_DITHER, GL_DITHER) @@ -6517,7 +6845,7 @@ function reglCore ( var drawCallCounter = 0 function createREGLEnvironment () { - var env = createEnvironment() + var env = createEnvironment({cache: cachedCode}) var link = env.link var global = env.global env.id = drawCallCounter++ @@ -8308,6 +8636,7 @@ function reglCore ( var CURRENT_VARS = env.current var CURRENT_STATE = shared.current var GL = shared.gl + var VALUE sortState(Object.keys(options)).forEach(function (param) { var defn = options[param] if (filter && !filter(defn)) { @@ -8317,17 +8646,17 @@ function reglCore ( if (GL_FLAGS[param]) { var flag = GL_FLAGS[param] if (isStatic(defn)) { - if (variable) { - scope(GL, '.enable(', flag, ');') - } else { - scope(GL, '.disable(', flag, ');') - } + VALUE = env.link(variable, {stable: true}) + scope(env.cond(VALUE) + .then(GL, '.enable(', flag, ');') + .else(GL, '.disable(', flag, ');')) + scope(CURRENT_STATE, '.', param, '=', VALUE, ';') } else { scope(env.cond(variable) .then(GL, '.enable(', flag, ');') .else(GL, '.disable(', flag, ');')) + scope(CURRENT_STATE, '.', param, '=', variable, ';') } - scope(CURRENT_STATE, '.', param, '=', variable, ';') } else if (isArrayLike(variable)) { var CURRENT = CURRENT_VARS[param] scope( @@ -8336,9 +8665,16 @@ function reglCore ( return CURRENT + '[' + i + ']=' + v }).join(';'), ';') } else { - scope( - GL, '.', GL_VARIABLES[param], '(', variable, ');', - CURRENT_STATE, '.', param, '=', variable, ';') + if (isStatic(defn)) { + VALUE = env.link(variable, {stable: true}) + scope( + GL, '.', GL_VARIABLES[param], '(', VALUE, ');', + CURRENT_STATE, '.', param, '=', VALUE, ';') + } else { + scope( + GL, '.', GL_VARIABLES[param], '(', variable, ');', + CURRENT_STATE, '.', param, '=', variable, ';') + } } }) } @@ -8580,25 +8916,12 @@ function reglCore ( var shared = env.shared var GL = shared.gl - var definedArrUniforms = {} var infix for (var i = 0; i < uniforms.length; ++i) { var uniform = uniforms[i] var name = uniform.name var type = uniform.info.type - var size = uniform.info.size var arg = args.uniforms[name] - if (size > 1) { - // either foo[n] or foos, avoid define both - if (!arg) { - continue - } - var arrUniformName = name.replace('[0]', '') - if (definedArrUniforms[arrUniformName]) { - continue - } - definedArrUniforms[arrUniformName] = 1 - } var UNIFORM = env.link(uniform) var LOCATION = UNIFORM + '.location' @@ -8652,99 +8975,74 @@ function reglCore ( } else { switch (type) { case GL_FLOAT$8: - if (size === 1) { - check$1.commandType(value, 'number', 'uniform ' + name, env.commandStr) - } else { - check$1.command( - isArrayLike(value) && (value.length === size), - 'uniform ' + name, env.commandStr) - } + check$1.commandType(value, 'number', 'uniform ' + name, env.commandStr) infix = '1f' break case GL_FLOAT_VEC2: check$1.command( - isArrayLike(value) && (value.length && value.length % 2 === 0 && value.length <= size * 2), + isArrayLike(value) && value.length === 2, 'uniform ' + name, env.commandStr) infix = '2f' break case GL_FLOAT_VEC3: check$1.command( - isArrayLike(value) && (value.length && value.length % 3 === 0 && value.length <= size * 3), + isArrayLike(value) && value.length === 3, 'uniform ' + name, env.commandStr) infix = '3f' break case GL_FLOAT_VEC4: check$1.command( - isArrayLike(value) && (value.length && value.length % 4 === 0 && value.length <= size * 4), + isArrayLike(value) && value.length === 4, 'uniform ' + name, env.commandStr) infix = '4f' break case GL_BOOL: - if (size === 1) { - check$1.commandType(value, 'boolean', 'uniform ' + name, env.commandStr) - } else { - check$1.command( - isArrayLike(value) && (value.length === size), - 'uniform ' + name, env.commandStr) - } + check$1.commandType(value, 'boolean', 'uniform ' + name, env.commandStr) infix = '1i' break case GL_INT$3: - if (size === 1) { - check$1.commandType(value, 'number', 'uniform ' + name, env.commandStr) - } else { - check$1.command( - isArrayLike(value) && (value.length === size), - 'uniform ' + name, env.commandStr) - } + check$1.commandType(value, 'number', 'uniform ' + name, env.commandStr) infix = '1i' break case GL_BOOL_VEC2: check$1.command( - isArrayLike(value) && (value.length && value.length % 2 === 0 && value.length <= size * 2), + isArrayLike(value) && value.length === 2, 'uniform ' + name, env.commandStr) infix = '2i' break case GL_INT_VEC2: check$1.command( - isArrayLike(value) && (value.length && value.length % 2 === 0 && value.length <= size * 2), + isArrayLike(value) && value.length === 2, 'uniform ' + name, env.commandStr) infix = '2i' break case GL_BOOL_VEC3: check$1.command( - isArrayLike(value) && (value.length && value.length % 3 === 0 && value.length <= size * 3), + isArrayLike(value) && value.length === 3, 'uniform ' + name, env.commandStr) infix = '3i' break case GL_INT_VEC3: check$1.command( - isArrayLike(value) && (value.length && value.length % 3 === 0 && value.length <= size * 3), + isArrayLike(value) && value.length === 3, 'uniform ' + name, env.commandStr) infix = '3i' break case GL_BOOL_VEC4: check$1.command( - isArrayLike(value) && (value.length && value.length % 4 === 0 && value.length <= size * 4), + isArrayLike(value) && value.length === 4, 'uniform ' + name, env.commandStr) infix = '4i' break case GL_INT_VEC4: check$1.command( - isArrayLike(value) && (value.length && value.length % 4 === 0 && value.length <= size * 4), + isArrayLike(value) && value.length === 4, 'uniform ' + name, env.commandStr) infix = '4i' break } - if (size > 1) { - infix += 'v' - value = env.global.def('[' + - Array.prototype.slice.call(value) + ']') - } else { - value = isArrayLike(value) ? Array.prototype.slice.call(value) : value - } scope(GL, '.uniform', infix, '(', LOCATION, ',', - value, + isArrayLike(value) ? Array.prototype.slice.call(value) : value, ');') } continue @@ -8779,24 +9077,20 @@ function reglCore ( 'bad data or missing for uniform "' + name + '". ' + message) } - function checkType (type, size) { - if (size === 1) { - check$1(!Array.isArray(VALUE), 'must not specify an array type for uniform') - } + function checkType (type) { + check$1(!Array.isArray(VALUE), 'must not specify an array type for uniform') emitCheck( - 'Array.isArray(' + VALUE + ') && typeof ' + VALUE + '[0]===" ' + type + '"' + - ' || typeof ' + VALUE + '==="' + type + '"', + 'typeof ' + VALUE + '==="' + type + '"', 'invalid type, expected ' + type) } - function checkVector (n, type, size) { + function checkVector (n, type) { if (Array.isArray(VALUE)) { - check$1(VALUE.length && VALUE.length % n === 0 && VALUE.length <= n * size, 'must have length of ' + (size === 1 ? '' : 'n * ') + n) + check$1(VALUE.length === n, 'must have length ' + n) } else { emitCheck( - shared.isArrayLike + '(' + VALUE + ')&&' + VALUE + '.length && ' + VALUE + '.length % ' + n + ' === 0' + - ' && ' + VALUE + '.length<=' + n * size, - 'invalid vector, should have length of ' + (size === 1 ? '' : 'n * ') + n, env.commandStr) + shared.isArrayLike + '(' + VALUE + ')&&' + VALUE + '.length===' + n, + 'invalid vector, should have length ' + n, env.commandStr) } } @@ -8811,49 +9105,49 @@ function reglCore ( switch (type) { case GL_INT$3: - checkType('number', size) + checkType('number') break case GL_INT_VEC2: - checkVector(2, 'number', size) + checkVector(2, 'number') break case GL_INT_VEC3: - checkVector(3, 'number', size) + checkVector(3, 'number') break case GL_INT_VEC4: - checkVector(4, 'number', size) + checkVector(4, 'number') break case GL_FLOAT$8: - checkType('number', size) + checkType('number') break case GL_FLOAT_VEC2: - checkVector(2, 'number', size) + checkVector(2, 'number') break case GL_FLOAT_VEC3: - checkVector(3, 'number', size) + checkVector(3, 'number') break case GL_FLOAT_VEC4: - checkVector(4, 'number', size) + checkVector(4, 'number') break case GL_BOOL: - checkType('boolean', size) + checkType('boolean') break case GL_BOOL_VEC2: - checkVector(2, 'boolean', size) + checkVector(2, 'boolean') break case GL_BOOL_VEC3: - checkVector(3, 'boolean', size) + checkVector(3, 'boolean') break case GL_BOOL_VEC4: - checkVector(4, 'boolean', size) + checkVector(4, 'boolean') break case GL_FLOAT_MAT2: - checkVector(4, 'number', size) + checkVector(4, 'number') break case GL_FLOAT_MAT3: - checkVector(9, 'number', size) + checkVector(9, 'number') break case GL_FLOAT_MAT4: - checkVector(16, 'number', size) + checkVector(16, 'number') break case GL_SAMPLER_2D: checkTexture(GL_TEXTURE_2D$3) @@ -8928,11 +9222,6 @@ function reglCore ( break } - if (infix.indexOf('Matrix') === -1 && size > 1) { - infix += 'v' - unroll = 1 - } - if (infix.charAt(0) === 'M') { scope(GL, '.uniform', infix, '(', LOCATION, ',') var matSize = Math.pow(type - GL_FLOAT_MAT2 + 2, 2) @@ -9470,10 +9759,18 @@ function reglCore ( var value = defn.append(env, scope) if (isArrayLike(value)) { value.forEach(function (v, i) { - scope.set(env.next[name], '[' + i + ']', v) + if (hasVariableReference(v)) { + scope.set(env.next[name], '[' + i + ']', v) + } else { + scope.set(env.next[name], '[' + i + ']', env.link(v, {stable: true})) + } }) } else { - scope.set(shared.next, '.' + name, value) + if (isStatic(defn)) { + scope.set(shared.next, '.' + name, env.link(value, {stable: true})) + } else { + scope.set(shared.next, '.' + name, value) + } } }) @@ -9485,17 +9782,28 @@ function reglCore ( if (!variable) { return } - scope.set(shared.draw, '.' + opt, '' + variable.append(env, scope)) + var VARIABLE = variable.append(env, scope) + if (hasVariableReference(VARIABLE)) { + scope.set(shared.draw, '.' + opt, VARIABLE) + } else { + scope.set(shared.draw, '.' + opt, env.link(VARIABLE), {stable: true}) + } }) Object.keys(args.uniforms).forEach(function (opt) { var value = args.uniforms[opt].append(env, scope) if (Array.isArray(value)) { - value = '[' + value.join() + ']' + value = '[' + value.map(function (v) { + if (hasVariableReference(v)) { + return v; + } else { + return env.link(v, {stable: true}) + } + }) + ']' } scope.set( shared.uniforms, - '[' + stringStore.id(opt) + ']', + '[' + env.link(stringStore.id(opt), {stable: true}) + ']', value) }) @@ -9508,13 +9816,23 @@ function reglCore ( }) if (args.scopeVAO) { - scope.set(shared.vao, '.targetVAO', args.scopeVAO.append(env, scope)) + var VARIABLE = args.scopeVAO.append(env, scope) + if (hasVariableReference(VARIABLE)) { + scope.set(shared.vao, '.targetVAO', VARIABLE) + } else { + scope.set(shared.vao, '.targetVAO', env.link(VARIABLE, {stable: true})) + } } function saveShader (name) { var shader = args.shader[name] if (shader) { - scope.set(shared.shader, '.' + name, shader.append(env, scope)) + var VARIABLE = shader.append(env, scope) + if (hasVariableReference(VARIABLE)) { + scope.set(shared.shader, '.' + name, VARIABLE) + } else { + scope.set(shared.shader, '.' + name, env.link(VARIABLE, {stable: true})) + } } } saveShader(S_VERT) @@ -9627,6 +9945,15 @@ function reglCore ( var args = parseArguments(options, attributes, uniforms, context, env) + if (args.shader.program) { + args.shader.program.attributes.sort(function (a, b) { + return a.name < b.name ? -1 : 1 + }) + args.shader.program.uniforms.sort(function (a, b) { + return a.name < b.name ? -1 : 1 + }) + } + emitDrawProc(env, args) emitScopeProc(env, args) emitBatchProc(env, args) @@ -9674,37 +10001,43 @@ function reglCore ( if (extensions.oes_vertex_array_object) { refresh(env.link(extensions.oes_vertex_array_object), '.bindVertexArrayOES(null);') } - for (var i = 0; i < limits.maxAttributes; ++i) { - var BINDING = refresh.def(shared.attributes, '[', i, ']') - var ifte = env.cond(BINDING, '.buffer') - ifte.then( - GL, '.enableVertexAttribArray(', i, ');', - GL, '.bindBuffer(', - GL_ARRAY_BUFFER$2, ',', - BINDING, '.buffer.buffer);', - GL, '.vertexAttribPointer(', - i, ',', - BINDING, '.size,', - BINDING, '.type,', - BINDING, '.normalized,', - BINDING, '.stride,', - BINDING, '.offset);' - ).else( - GL, '.disableVertexAttribArray(', i, ');', - GL, '.vertexAttrib4f(', - i, ',', - BINDING, '.x,', - BINDING, '.y,', - BINDING, '.z,', - BINDING, '.w);', - BINDING, '.buffer=null;') - refresh(ifte) - if (extInstancing) { - refresh( - INSTANCING, '.vertexAttribDivisorANGLE(', - i, ',', - BINDING, '.divisor);') - } + var BINDING = refresh.def(shared.attributes) + var TEMP_BINDING = refresh.def(0) + + var ifte = env.cond(TEMP_BINDING, '.buffer') + ifte.then( + GL, '.enableVertexAttribArray(i);', + GL, '.bindBuffer(', + GL_ARRAY_BUFFER$2, ',', + TEMP_BINDING, '.buffer.buffer);', + GL, '.vertexAttribPointer(i,', + TEMP_BINDING, '.size,', + TEMP_BINDING, '.type,', + TEMP_BINDING, '.normalized,', + TEMP_BINDING, '.stride,', + TEMP_BINDING, '.offset);' + ).else( + GL, '.disableVertexAttribArray(i);', + GL, '.vertexAttrib4f(i,', + TEMP_BINDING, '.x,', + TEMP_BINDING, '.y,', + TEMP_BINDING, '.z,', + TEMP_BINDING, '.w);', + TEMP_BINDING, '.buffer=null;') + var MAX_ATTRIBUTES = env.link(limits.maxAttributes, {stable: true}) + refresh( + 'for(var i=0;i<', MAX_ATTRIBUTES, ';++i){', + TEMP_BINDING, '=', BINDING, '[i];', + ifte, + '}' + ) + + if (extInstancing) { + refresh( + 'for(var i=0;i<', MAX_ATTRIBUTES, ';++i){', + INSTANCING, '.vertexAttribDivisorANGLE(i,', + BINDING, '[i].divisor);', + '}') } refresh( env.shared.vao, '.currentVAO=null;', @@ -9958,6 +10291,7 @@ function wrapREGL (args) { var stringStore = createStringStore() var stats$$1 = stats() + var cachedCode = config.cachedCode || {}; var extensions = extensionState.extensions var timer = createTimer(gl, extensions) @@ -10035,6 +10369,7 @@ function wrapREGL (args) { drawState, contextState, timer, + cachedCode, config) var readPixels = wrapReadPixels( gl, @@ -10453,6 +10788,16 @@ function wrapREGL (args) { } } + function getCachedCode() { + return cachedCode + } + + function preloadCachedCode(moreCache) { + Object.entries(moreCache).forEach(function (kv) { + cachedCode[kv[0]] = kv[1] + }) + } + var regl = extend(compileProcedure, { // Clear current FBO clear: clear, @@ -10513,7 +10858,11 @@ function wrapREGL (args) { now: now, // regl Statistics Information - stats: stats$$1 + stats: stats$$1, + + // cache generated code + getCachedCode: getCachedCode, + preloadCachedCode: preloadCachedCode }) config.onDone(null, regl) diff --git a/dist/regl.js.map b/dist/regl.js.map index 19989870..92b3628d 100644 --- a/dist/regl.js.map +++ b/dist/regl.js.map @@ -1 +1 @@ -{"version":3,"file":null,"sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file +{"version":3,"file":null,"sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file diff --git a/dist/regl.min.js b/dist/regl.min.js index 8b682601..8679058e 100644 --- a/dist/regl.min.js +++ b/dist/regl.min.js @@ -1,171 +1,177 @@ -(function(Z,ka){"object"===typeof exports&&"undefined"!==typeof module?module.exports=ka():"function"===typeof define&&define.amd?define(ka):Z.createREGL=ka()})(this,function(){function Z(a,b){this.id=Db++;this.type=a;this.data=b}function ka(a){if(0===a.length)return[];var b=a.charAt(0),c=a.charAt(a.length-1);if(1>>=b;c=(255>>=c;b|=c;c=(15>>=c;b|=c;c=(3>>c>>1}function hb(){function a(a){a:{for(var b=16;268435456>=b;b*=16)if(a<=b){a=b;break a}a=0}b=c[gb(a)>>2];return 0>2].push(a)}var c=R(8,function(){return[]});return{alloc:a,free:b,allocType:function(b,c){var d=null;switch(b){case 5120:d=new Int8Array(a(c),0,c);break;case 5121:d=new Uint8Array(a(c),0,c);break;case 5122:d=new Int16Array(a(2*c),0,c);break;case 5123:d=new Uint16Array(a(2*c),0,c);break;case 5124:d=new Int32Array(a(4*c),0,c);break;case 5125:d=new Uint32Array(a(4*c),0,c);break;case 5126:d=new Float32Array(a(4*c),0,c);break;default:return null}return d.length!== -c?d.subarray(0,c):d},freeType:function(a){b(a.buffer)}}}function la(a){return!!a&&"object"===typeof a&&Array.isArray(a.shape)&&Array.isArray(a.stride)&&"number"===typeof a.offset&&a.shape.length===a.stride.length&&(Array.isArray(a.data)||O(a.data))}function ib(a,b,c,e,f,d){for(var q=0;qe&&(e=d.buffer.byteLength,5123===k?e>>=1:5125===k&&(e>>=2));d.vertCount=e;e=g;0>g&&(e=4,g=d.buffer.dimension,1===g&&(e=0),2===g&&(e=1),3===g&&(e=4));d.primType=e}function q(a){e.elementsCount--;delete n[a.id];a.buffer.destroy();a.buffer=null}var n={},v=0,k={uint8:5121,uint16:5123};b.oes_element_index_uint&&(k.uint32=5125);f.prototype.bind=function(){this.buffer.bind()};var u=[];return{create:function(a, -b){function l(a){if(a)if("number"===typeof a)g(a),h.primType=4,h.vertCount=a|0,h.type=5121;else{var b=null,c=35044,e=-1,f=-1,m=0,n=0;if(Array.isArray(a)||O(a)||la(a))b=a;else if("data"in a&&(b=a.data),"usage"in a&&(c=nb[a.usage]),"primitive"in a&&(e=Ka[a.primitive]),"count"in a&&(f=a.count|0),"type"in a&&(n=k[a.type]),"length"in a)m=a.length|0;else if(m=f,5123===n||5122===n)m*=2;else if(5125===n||5124===n)m*=4;d(h,b,c,e,f,m,n)}else g(),h.primType=4,h.vertCount=0,h.type=5121;return l}var g=c.create(null, -34963,!0),h=new f(g._buffer);e.elementsCount++;l(a);l._reglType="elements";l._elements=h;l.subdata=function(a,b){g.subdata(a,b);return l};l.destroy=function(){q(h)};return l},createStream:function(a){var b=u.pop();b||(b=new f(c.create(null,34963,!0,!1)._buffer));d(b,a,35040,-1,-1,0,0);return b},destroyStream:function(a){u.push(a)},getElements:function(a){return"function"===typeof a&&a._elements instanceof f?a._elements:null},clear:function(){I(n).forEach(q)}}}function ob(a){for(var b=G.allocType(5123, -a.length),c=0;c>>31<<15,d=(e<<1>>>24)-127,e=e>>13&1023;b[c]=-24>d?f:-14>d?f+(e+1024>>-14-d):15>=e,c.height>>=e,x(c,d[e]),a.mipmask|=1<b;++b)a.images[b]=null;return a}function ya(a){for(var b=a.images,c=0;cb){for(var c=0;c=--this.refCount&&F(this)}});q.profile&&(d.getTotalTextureSize=function(){var a=0;Object.keys(ea).forEach(function(b){a+=ea[b].stats.size});return a});return{create2D:function(b,c){function e(a,b){var c=f.texInfo;w.call(c);var d=ma();"number"===typeof a?"number"===typeof b?p(d,a|0,b|0):p(d,a|0,a|0):a?(H(c,a),P(d,a)):p(d,1,1);c.genMipmaps&&(d.mipmask=(d.width<<1)-1);f.mipmask=d.mipmask;v(f, -d);f.internalformat=d.internalformat;e.width=d.width;e.height=d.height;T(f);t(d,3553);M(c,3553);wa();ya(d);q.profile&&(f.stats.size=La(f.internalformat,f.type,d.width,d.height,c.genMipmaps,!1));e.format=ca[f.internalformat];e.type=K[f.type];e.mag=Fa[c.magFilter];e.min=pa[c.minFilter];e.wrapS=qa[c.wrapS];e.wrapT=qa[c.wrapT];return e}var f=new y(3553);ea[f.id]=f;d.textureCount++;e(b,c);e.subimage=function(a,b,c,d){b|=0;c|=0;d|=0;var y=g();v(y,f);y.width=0;y.height=0;x(y,a);y.width=y.width||(f.width>> -d)-b;y.height=y.height||(f.height>>d)-c;T(f);l(y,3553,b,c,d);wa();h(y);return e};e.resize=function(b,c){var d=b|0,g=c|0||d;if(d===f.width&&g===f.height)return e;e.width=f.width=d;e.height=f.height=g;T(f);for(var y=0;f.mipmask>>y;++y){var h=d>>y,z=g>>y;if(!h||!z)break;a.texImage2D(3553,y,f.format,h,z,0,f.format,f.type,null)}wa();q.profile&&(f.stats.size=La(f.internalformat,f.type,d,g,!1,!1));return e};e._reglType="texture2d";e._texture=f;q.profile&&(e.stats=f.stats);e.destroy=function(){f.decRef()}; -return e},createCube:function(b,c,e,f,n,r){function m(a,b,c,d,e,f){var g,da=A.texInfo;w.call(da);for(g=0;6>g;++g)F[g]=ma();if("number"===typeof a||!a)for(a=a|0||1,g=0;6>g;++g)p(F[g],a,a);else if("object"===typeof a)if(b)P(F[0],a),P(F[1],b),P(F[2],c),P(F[3],d),P(F[4],e),P(F[5],f);else if(H(da,a),k(A,a),"faces"in a)for(a=a.faces,g=0;6>g;++g)v(F[g],A),P(F[g],a[g]);else for(g=0;6>g;++g)P(F[g],a);v(A,F[0]);A.mipmask=da.genMipmaps?(F[0].width<<1)-1:F[0].mipmask;A.internalformat=F[0].internalformat;m.width= -F[0].width;m.height=F[0].height;T(A);for(g=0;6>g;++g)t(F[g],34069+g);M(da,34067);wa();q.profile&&(A.stats.size=La(A.internalformat,A.type,m.width,m.height,da.genMipmaps,!0));m.format=ca[A.internalformat];m.type=K[A.type];m.mag=Fa[da.magFilter];m.min=pa[da.minFilter];m.wrapS=qa[da.wrapS];m.wrapT=qa[da.wrapT];for(g=0;6>g;++g)ya(F[g]);return m}var A=new y(34067);ea[A.id]=A;d.cubeCount++;var F=Array(6);m(b,c,e,f,n,r);m.subimage=function(a,b,c,d,e){c|=0;d|=0;e|=0;var f=g();v(f,A);f.width=0;f.height=0; -x(f,b);f.width=f.width||(A.width>>e)-c;f.height=f.height||(A.height>>e)-d;T(A);l(f,34069+a,c,d,e);wa();h(f);return m};m.resize=function(b){b|=0;if(b!==A.width){m.width=A.width=b;m.height=A.height=b;T(A);for(var c=0;6>c;++c)for(var d=0;A.mipmask>>d;++d)a.texImage2D(34069+c,d,A.format,b>>d,b>>d,0,A.format,A.type,null);wa();q.profile&&(A.stats.size=La(A.internalformat,A.type,m.width,m.height,!1,!0));return m}};m._reglType="textureCube";m._texture=A;q.profile&&(m.stats=A.stats);m.destroy=function(){A.decRef()}; -return m},clear:function(){for(var b=0;bc;++c)if(0!==(b.mipmask&1<>c,b.height>>c,0,b.internalformat, -b.type,null);else for(var d=0;6>d;++d)a.texImage2D(34069+d,c,b.internalformat,b.width>>c,b.height>>c,0,b.internalformat,b.type,null);M(b.texInfo,b.target)})},refresh:function(){for(var b=0;bd;++d){for(p= -0;pa;++a)c[a].resize(d);b.width=b.height=d;return b},_reglType:"framebufferCube",destroy:function(){c.forEach(function(a){a.destroy()})}})},clear:function(){I(M).forEach(r)}, -restore:function(){t.cur=null;t.next=null;t.dirty=!0;I(M).forEach(function(b){b.framebuffer=a.createFramebuffer();p(b)})}})}function $a(){this.w=this.z=this.y=this.x=this.state=0;this.buffer=null;this.size=0;this.normalized=!1;this.type=5126;this.divisor=this.stride=this.offset=0}function Sb(a,b,c,e,f,d,q){function n(a){if(a!==r.currentVAO){var c=b.oes_vertex_array_object;a?c.bindVertexArrayOES(a.vao):c.bindVertexArrayOES(null);r.currentVAO=a}}function v(c){if(c!==r.currentVAO){if(c)c.bindAttrs(); -else{for(var d=b.angle_instanced_arrays,e=0;e=m.byteLength?l.subdata(m): -(l.destroy(),c.buffers[h]=null));c.buffers[h]||(l=c.buffers[h]=f.create(p,34962,!1,!0));k.buffer=f.getBuffer(l);k.size=k.buffer.dimension|0;k.normalized=!1;k.type=k.buffer.dtype;k.offset=0;k.stride=0;k.divisor=0;k.state=1;a[h]=1}else f.getBuffer(p)?(k.buffer=f.getBuffer(p),k.size=k.buffer.dimension|0,k.normalized=!1,k.type=k.buffer.dtype,k.offset=0,k.stride=0,k.divisor=0,k.state=1):f.getBuffer(p.buffer)?(k.buffer=f.getBuffer(p.buffer),k.size=(+p.size||k.buffer.dimension)|0,k.normalized=!!p.normalized|| -!1,k.type="type"in p?Ja[p.type]:k.buffer.dtype,k.offset=(p.offset||0)|0,k.stride=(p.stride||0)|0,k.divisor=(p.divisor||0)|0,k.state=1):"x"in p&&(k.x=+p.x||0,k.y=+p.y||0,k.z=+p.z||0,k.w=+p.w||0,k.state=2)}for(l=0;la&&(a=b.stats.uniformsCount)});return a},c.getMaxAttributesCount=function(){var a=0;x.forEach(function(b){b.stats.attributesCount>a&&(a=b.stats.attributesCount)});return a});return{clear:function(){var b=a.deleteShader.bind(a);I(k).forEach(b);k={};I(u).forEach(b); -u={};x.forEach(function(b){a.deleteProgram(b.program)});x.length=0;m={};c.shaderCount=0},program:function(b,d,e,f){var l=m[d];l||(l=m[d]={});var q=l[b];if(q&&(q.refCount++,!f))return q;var w=new n(d,b);c.shaderCount++;v(w,e,f);q||(l[b]=w);x.push(w);return L(w,{destroy:function(){w.refCount--;if(0>=w.refCount){a.deleteProgram(w.program);var b=x.indexOf(w);x.splice(b,1);c.shaderCount--}0>=l[w.vertId].refCount&&(a.deleteShader(u[w.vertId]),delete u[w.vertId],delete m[w.fragId][w.vertId]);Object.keys(m[w.fragId]).length|| -(a.deleteShader(k[w.fragId]),delete k[w.fragId],delete m[w.fragId])}})},restore:function(){k={};u={};for(var a=0;a"+b+"?"+e+".constant["+b+"]:0;"}).join(""),"}}else{","if(",g,"(",e,".buffer)){",k,"=",f,".createStream(",34962,",",e,".buffer);","}else{",k,"=",f,".getBuffer(",e,".buffer);","}",m,'="type" in ',e,"?",z.glTypes,"[",e,".type]:",k,".dtype;",B.normalized,"=!!", -e,".normalized;");d("size");d("offset");d("stride");d("divisor");c("}}");c.exit("if(",B.isStream,"){",f,".destroyStream(",k,");","}");return B})});return g}function F(a){var b=a["static"],c=a.dynamic,d={};Object.keys(b).forEach(function(a){var c=b[a];d[a]=w(function(a,b){return"number"===typeof c||"boolean"===typeof c?""+c:a.link(c)})});Object.keys(c).forEach(function(a){var b=c[a];d[a]=K(b,function(a,c){return a.invoke(c,b)})});return d}function A(a,b,d,e,f){function g(a){var b=p[a];b&&(ja[a]=b)} -var m=O(a,b),l=G(a,f),p=C(a,l,f),X=M(a,f),ja=y(a,f),q=H(a,f,m);g("viewport");g(h("scissor.box"));var n=0>1)",u],");")}function b(){c(t,".drawArraysInstancedANGLE(",[n,q,r,u],");")}p&&"null"!==p?v?a():(c("if(",p,"){"),a(),c("}else{"),b(),c("}")):b()}function g(){function a(){c(l+".drawElements("+[n,r,x,q+"<<(("+x+"-5121)>>1)"]+");")}function b(){c(l+".drawArrays("+[n,q,r]+");")}p&&"null"!==p?v?a():(c("if(",p,"){"),a(),c("}else{"),b(),c("}")):b()}var h=a.shared,l=h.gl,k=h.draw,m=d.draw, -p=function(){var e=m.elements,f=b;if(e){if(e.contextDep&&d.contextDynamic||e.propDep)f=c;e=e.append(a,f);m.elementsActive&&f("if("+e+")"+l+".bindBuffer(34963,"+e+".buffer.buffer);")}else e=f.def(),f(e,"=",k,".","elements",";","if(",e,"){",l,".bindBuffer(",34963,",",e,".buffer.buffer);}","else if(",h.vao,".currentVAO){",e,"=",a.shared.elements+".getElements("+h.vao,".currentVAO.elements);",na?"":"if("+e+")"+l+".bindBuffer(34963,"+e+".buffer.buffer);","}");return e}(),n=e("primitive"),q=e("offset"), -r=function(){var e=m.count,f=b;if(e){if(e.contextDep&&d.contextDynamic||e.propDep)f=c;e=e.append(a,f)}else e=f.def(k,".","count");return e}();if("number"===typeof r){if(0===r)return}else c("if(",r,"){"),c.exit("}");var u,t;W&&(u=e("instances"),t=a.instancing);var x=p+".type",v=m.elements&&xa(m.elements)&&!m.vaoActive;W&&("number"!==typeof u||0<=u)?"string"===typeof u?(c("if(",u,">0){"),f(),c("}else if(",u,"<0){"),g(),c("}")):f():g()}function ca(a,b,c,d,e){b=P();e=b.proc("body",e);W&&(b.instancing= -e.def(b.shared.extensions,".angle_instanced_arrays"));a(b,e,c,d);return b.compile().body}function Z(a,b,c,d){N(a,b);c.useVAO?c.drawVAO?b(a.shared.vao,".setVAO(",c.drawVAO.append(a,b),");"):b(a.shared.vao,".setVAO(",a.shared.vao,".targetVAO);"):(b(a.shared.vao,".setVAO(null);"),ga(a,b,c,d.attributes,function(){return!0}));Q(a,b,c,d.uniforms,function(){return!0},!1);U(a,b,b,c)}function Fa(a,b){var c=a.proc("draw",1);N(a,c);ia(a,c,b.context);S(a,c,b.framebuffer);Aa(a,c,b);I(a,c,b.state);E(a,c,b,!1,!0); -var d=b.shader.progVar.append(a,c);c(a.shared.gl,".useProgram(",d,".program);");if(b.shader.program)Z(a,c,b,b.shader.program);else{c(a.shared.vao,".setVAO(null);");var e=a.global.def("{}"),f=c.def(d,".id"),g=c.def(e,"[",f,"]");c(a.cond(g).then(g,".call(this,a0);")["else"](g,"=",e,"[",f,"]=",a.link(function(c){return ca(Z,a,b,c,1)}),"(",d,");",g,".call(this,a0);"))}0=--this.refCount&&q(this)};f.profile&&(e.getTotalRenderbufferSize=function(){var a=0;Object.keys(u).forEach(function(b){a+=u[b].stats.size});return a});return{create:function(b, -c){function l(b,c){var d=0,e=0,k=32854;"object"===typeof b&&b?("shape"in b?(e=b.shape,d=e[0]|0,e=e[1]|0):("radius"in b&&(d=e=b.radius|0),"width"in b&&(d=b.width|0),"height"in b&&(e=b.height|0)),"format"in b&&(k=n[b.format])):"number"===typeof b?(d=b|0,e="number"===typeof c?c|0:d):b||(d=e=1);if(d!==g.width||e!==g.height||k!==g.format)return l.width=g.width=d,l.height=g.height=e,g.format=k,a.bindRenderbuffer(36161,g.renderbuffer),a.renderbufferStorage(36161,k,d,e),f.profile&&(g.stats.size=Q[g.format]* -g.width*g.height),l.format=v[g.format],l}var g=new d(a.createRenderbuffer());u[g.id]=g;e.renderbufferCount++;l(b,c);l.resize=function(b,c){var d=b|0,e=c|0||d;if(d===g.width&&e===g.height)return l;l.width=g.width=d;l.height=g.height=e;a.bindRenderbuffer(36161,g.renderbuffer);a.renderbufferStorage(36161,g.format,d,e);f.profile&&(g.stats.size=Q[g.format]*g.width*g.height);return l};l._reglType="renderbuffer";l._renderbuffer=g;f.profile&&(l.stats=g.stats);l.destroy=function(){g.decRef()};return l},clear:function(){I(u).forEach(q)}, -restore:function(){I(u).forEach(function(b){b.renderbuffer=a.createRenderbuffer();a.bindRenderbuffer(36161,b.renderbuffer);a.renderbufferStorage(36161,b.format,b.width,b.height)});a.bindRenderbuffer(36161,null)}}},Za=[];Za[6408]=4;Za[6407]=3;var Ra=[];Ra[5121]=1;Ra[5126]=4;Ra[36193]=2;var Da=["x","y","z","w"],Xb="blend.func blend.equation stencil.func stencil.opFront stencil.opBack sample.coverage viewport scissor.box polygonOffset.offset".split(" "),Ga={0:0,1:1,zero:0,one:1,"src color":768,"one minus src color":769, -"src alpha":770,"one minus src alpha":771,"dst color":774,"one minus dst color":775,"dst alpha":772,"one minus dst alpha":773,"constant color":32769,"one minus constant color":32770,"constant alpha":32771,"one minus constant alpha":32772,"src alpha saturate":776},ab={never:512,less:513,"<":513,equal:514,"=":514,"==":514,"===":514,lequal:515,"<=":515,greater:516,">":516,notequal:517,"!=":517,"!==":517,gequal:518,">=":518,always:519},Ta={0:0,zero:0,keep:7680,replace:7681,increment:7682,decrement:7683, -"increment wrap":34055,"decrement wrap":34056,invert:5386},zb={cw:2304,ccw:2305},Ab=new J(!1,!1,!1,function(){}),$b=function(a,b){function c(){this.endQueryIndex=this.startQueryIndex=-1;this.sum=0;this.stats=null}function e(a,b,d){var e=q.pop()||new c;e.startQueryIndex=a;e.endQueryIndex=b;e.sum=0;e.stats=d;n.push(e)}if(!b.ext_disjoint_timer_query)return null;var f=[],d=[],q=[],n=[],v=[],k=[];return{beginQuery:function(a){var c=f.pop()||b.ext_disjoint_timer_query.createQueryEXT();b.ext_disjoint_timer_query.beginQueryEXT(35007, -c);d.push(c);e(d.length-1,d.length,a)},endQuery:function(){b.ext_disjoint_timer_query.endQueryEXT(35007)},pushScopeStats:e,update:function(){var a,c;a=d.length;if(0!==a){k.length=Math.max(k.length,a+1);v.length=Math.max(v.length,a+1);v[0]=0;var e=k[0]=0;for(c=a=0;c=E.length&&e()}var c=Bb(E,a);E[c]=b}}}function k(){var a=Q.viewport,b=Q.scissor_box;a[0]=a[1]=b[0]=b[1]=0;H.viewportWidth=H.framebufferWidth=H.drawingBufferWidth=a[2]=b[2]=l.drawingBufferWidth;H.viewportHeight=H.framebufferHeight=H.drawingBufferHeight=a[3]=b[3]=l.drawingBufferHeight}function u(){H.tick+=1;H.time=x();k();I.procs.poll()}function m(){A.refresh();k();I.procs.refresh();t&&t.update()}function x(){return(Cb()- -G)/1E3}a=Hb(a);if(!a)return null;var l=a.gl,g=l.getContextAttributes();l.isContextLost();var h=Ib(l,a);if(!h)return null;var r=Eb(),p={vaoCount:0,bufferCount:0,elementsCount:0,framebufferCount:0,shaderCount:0,textureCount:0,cubeCount:0,renderbufferCount:0,maxTextureUnits:0},w=h.extensions,t=$b(l,w),G=Cb(),C=l.drawingBufferWidth,J=l.drawingBufferHeight,H={tick:0,time:0,viewportWidth:C,viewportHeight:J,framebufferWidth:C,framebufferHeight:J,drawingBufferWidth:C,drawingBufferHeight:J,pixelRatio:a.pixelRatio}, -C={elements:null,primitive:4,count:-1,offset:0,instances:-1},M=Yb(l,w),y=Jb(l,p,a,function(a){return K.destroyBuffer(a)}),T=Kb(l,w,y,p),K=Sb(l,w,M,p,y,T,C),F=Tb(l,r,p,a),A=Nb(l,w,M,function(){I.procs.poll()},H,p,a),O=Zb(l,w,M,p,a),S=Rb(l,w,M,A,O,p),I=Wb(l,r,w,M,y,T,A,S,{},K,F,C,H,t,a),r=Ub(l,S,I.procs.poll,H,g,w,M),Q=I.next,N=l.canvas,E=[],R=[],U=[],Z=[a.onDestroy],ca=null;N&&(N.addEventListener("webglcontextlost",f,!1),N.addEventListener("webglcontextrestored",d,!1));var aa=S.setFBO=q({framebuffer:Y.define.call(null, -1,"framebuffer")});m();g=L(q,{clear:function(a){if("framebuffer"in a)if(a.framebuffer&&"framebufferCube"===a.framebuffer_reglType)for(var b=0;6>b;++b)aa(L({framebuffer:a.framebuffer.faces[b]},a),n);else aa(a,n);else n(null,a)},prop:Y.define.bind(null,1),context:Y.define.bind(null,2),"this":Y.define.bind(null,3),draw:q({}),buffer:function(a){return y.create(a,34962,!1,!1)},elements:function(a){return T.create(a,!1)},texture:A.create2D,cube:A.createCube,renderbuffer:O.create,framebuffer:S.create,framebufferCube:S.createCube, -vao:K.createVAO,attributes:g,frame:v,on:function(a,b){var c;switch(a){case "frame":return v(b);case "lost":c=R;break;case "restore":c=U;break;case "destroy":c=Z}c.push(b);return{cancel:function(){for(var a=0;a>>=b;c=(255>>=c;b|=c;c=(15>>=c;b|=c;c=(3>>c>>1}function gb(){function a(a){a:{for(var b=16;268435456>=b;b*=16)if(a<=b){a=b;break a}a=0}b=c[fb(a)>>2];return 0>2].push(a)}var c=S(8,function(){return[]});return{alloc:a,free:b,allocType:function(b,c){var e=null;switch(b){case 5120:e=new Int8Array(a(c),0,c);break;case 5121:e=new Uint8Array(a(c),0,c);break;case 5122:e=new Int16Array(a(2*c),0,c);break;case 5123:e=new Uint16Array(a(2*c),0,c);break;case 5124:e=new Int32Array(a(4*c),0,c);break;case 5125:e=new Uint32Array(a(4*c),0,c);break;case 5126:e=new Float32Array(a(4*c),0,c);break;default:return null}return e.length!== +c?e.subarray(0,c):e},freeType:function(a){b(a.buffer)}}}function fa(a){return!!a&&"object"===typeof a&&Array.isArray(a.shape)&&Array.isArray(a.stride)&&"number"===typeof a.offset&&a.shape.length===a.stride.length&&(Array.isArray(a.data)||P(a.data))}function hb(a,b,c,d,f,e){for(var m=0;me&&(e=d.buffer.byteLength,5123===k?e>>=1:5125===k&&(e>>=2));d.vertCount=e;e=l;0>l&&(e=4,l=d.buffer.dimension,1===l&&(e=0),2===l&&(e=1),3===l&&(e=4));d.primType=e}function m(a){d.elementsCount--;delete q[a.id];a.buffer.destroy();a.buffer=null}var q={},u=0,r={uint8:5121,uint16:5123};b.oes_element_index_uint&&(r.uint32=5125);f.prototype.bind=function(){this.buffer.bind()};var k=[];return{create:function(a, +b){function g(a){if(a)if("number"===typeof a)l(a),h.primType=4,h.vertCount=a|0,h.type=5121;else{var b=null,c=35044,d=-1,f=-1,n=0,k=0;if(Array.isArray(a)||P(a)||fa(a))b=a;else if("data"in a&&(b=a.data),"usage"in a&&(c=mb[a.usage]),"primitive"in a&&(d=Ka[a.primitive]),"count"in a&&(f=a.count|0),"type"in a&&(k=r[a.type]),"length"in a)n=a.length|0;else if(n=f,5123===k||5122===k)n*=2;else if(5125===k||5124===k)n*=4;e(h,b,c,d,f,n,k)}else l(),h.primType=4,h.vertCount=0,h.type=5121;return g}var l=c.create(null, +34963,!0),h=new f(l._buffer);d.elementsCount++;g(a);g._reglType="elements";g._elements=h;g.subdata=function(a,b){l.subdata(a,b);return g};g.destroy=function(){m(h)};return g},createStream:function(a){var b=k.pop();b||(b=new f(c.create(null,34963,!0,!1)._buffer));e(b,a,35040,-1,-1,0,0);return b},destroyStream:function(a){k.push(a)},getElements:function(a){return"function"===typeof a&&a._elements instanceof f?a._elements:null},clear:function(){T(q).forEach(m)}}}function ob(a){for(var b=B.allocType(5123, +a.length),c=0;c>>31<<15,e=(d<<1>>>24)-127,d=d>>13&1023;b[c]=-24>e?f:-14>e?f+(d+1024>>-14-e):15>=e,c.height>>=e,t(c,d[e]),a.mipmask|=1<b;++b)a.images[b]=null;return a}function wa(a){for(var b=a.images,c=0;cb){for(var c=0;c=--this.refCount&&A(this)}});m.profile&&(e.getTotalTextureSize=function(){var a=0;Object.keys(ka).forEach(function(b){a+=ka[b].stats.size});return a});return{create2D:function(b,c){function d(a,b){var c=f.texInfo;E.call(c);var e=z();"number"===typeof a?"number"===typeof b?y(e,a|0,b|0):y(e,a|0,a|0):a?(nb(c,a),C(e,a)):y(e,1,1);c.genMipmaps&&(e.mipmask=(e.width<<1)-1);f.mipmask=e.mipmask;u(f, +e);f.internalformat=e.internalformat;d.width=e.width;d.height=e.height;ba(f);w(e,3553);D(c,3553);za();wa(e);m.profile&&(f.stats.size=La(f.internalformat,f.type,e.width,e.height,c.genMipmaps,!1));d.format=H[f.internalformat];d.type=xa[f.type];d.mag=L[c.magFilter];d.min=pa[c.minFilter];d.wrapS=ga[c.wrapS];d.wrapT=ga[c.wrapT];return d}var f=new v(3553);ka[f.id]=f;e.textureCount++;d(b,c);d.subimage=function(a,b,c,e){b|=0;c|=0;e|=0;var v=l();u(v,f);v.width=0;v.height=0;t(v,a);v.width=v.width||(f.width>> +e)-b;v.height=v.height||(f.height>>e)-c;ba(f);g(v,3553,b,c,e);za();h(v);return d};d.resize=function(b,c){var e=b|0,h=c|0||e;if(e===f.width&&h===f.height)return d;d.width=f.width=e;d.height=f.height=h;ba(f);for(var g=0;f.mipmask>>g;++g){var v=e>>g,l=h>>g;if(!v||!l)break;a.texImage2D(3553,g,f.format,v,l,0,f.format,f.type,null)}za();m.profile&&(f.stats.size=La(f.internalformat,f.type,e,h,!1,!1));return d};d._reglType="texture2d";d._texture=f;m.profile&&(d.stats=f.stats);d.destroy=function(){f.decRef()}; +return d},createCube:function(b,c,d,f,k,n){function p(a,b,c,d,e,h){var f,g=A.texInfo;E.call(g);for(f=0;6>f;++f)J[f]=z();if("number"===typeof a||!a)for(a=a|0||1,f=0;6>f;++f)y(J[f],a,a);else if("object"===typeof a)if(b)C(J[0],a),C(J[1],b),C(J[2],c),C(J[3],d),C(J[4],e),C(J[5],h);else if(nb(g,a),r(A,a),"faces"in a)for(a=a.faces,f=0;6>f;++f)u(J[f],A),C(J[f],a[f]);else for(f=0;6>f;++f)C(J[f],a);u(A,J[0]);A.mipmask=g.genMipmaps?(J[0].width<<1)-1:J[0].mipmask;A.internalformat=J[0].internalformat;p.width= +J[0].width;p.height=J[0].height;ba(A);for(f=0;6>f;++f)w(J[f],34069+f);D(g,34067);za();m.profile&&(A.stats.size=La(A.internalformat,A.type,p.width,p.height,g.genMipmaps,!0));p.format=H[A.internalformat];p.type=xa[A.type];p.mag=L[g.magFilter];p.min=pa[g.minFilter];p.wrapS=ga[g.wrapS];p.wrapT=ga[g.wrapT];for(f=0;6>f;++f)wa(J[f]);return p}var A=new v(34067);ka[A.id]=A;e.cubeCount++;var J=Array(6);p(b,c,d,f,k,n);p.subimage=function(a,b,c,d,e){c|=0;d|=0;e|=0;var f=l();u(f,A);f.width=0;f.height=0;t(f,b); +f.width=f.width||(A.width>>e)-c;f.height=f.height||(A.height>>e)-d;ba(A);g(f,34069+a,c,d,e);za();h(f);return p};p.resize=function(b){b|=0;if(b!==A.width){p.width=A.width=b;p.height=A.height=b;ba(A);for(var c=0;6>c;++c)for(var x=0;A.mipmask>>x;++x)a.texImage2D(34069+c,x,A.format,b>>x,b>>x,0,A.format,A.type,null);za();m.profile&&(A.stats.size=La(A.internalformat,A.type,p.width,p.height,!1,!0));return p}};p._reglType="textureCube";p._texture=A;m.profile&&(p.stats=A.stats);p.destroy=function(){A.decRef()}; +return p},clear:function(){for(var b=0;bc;++c)if(0!==(b.mipmask&1<>c,b.height>>c,0,b.internalformat, +b.type,null);else for(var d=0;6>d;++d)a.texImage2D(34069+d,c,b.internalformat,b.width>>c,b.height>>c,0,b.internalformat,b.type,null);D(b.texInfo,b.target)})},refresh:function(){for(var b=0;be;++e){for(k=0;ka;++a)c[a].resize(d);b.width=b.height=d;return b},_reglType:"framebufferCube",destroy:function(){c.forEach(function(a){a.destroy()})}})}, +clear:function(){T(D).forEach(p)},restore:function(){w.cur=null;w.next=null;w.dirty=!0;T(D).forEach(function(b){b.framebuffer=a.createFramebuffer();y(b)})}})}function Za(){this.w=this.z=this.y=this.x=this.state=0;this.buffer=null;this.size=0;this.normalized=!1;this.type=5126;this.divisor=this.stride=this.offset=0}function Rb(a,b,c,d,f,e,m){function q(a){if(a!==p.currentVAO){var c=b.oes_vertex_array_object;a?c.bindVertexArrayOES(a.vao):c.bindVertexArrayOES(null);p.currentVAO=a}}function u(c){if(c!== +p.currentVAO){if(c)c.bindAttrs();else{for(var d=b.angle_instanced_arrays,e=0;e=n.byteLength?p.subdata(n):(p.destroy(),c.buffers[h]=null));c.buffers[h]||(p=c.buffers[h]=f.create(l,34962,!1,!0));k.buffer=f.getBuffer(p);k.size=k.buffer.dimension|0;k.normalized=!1;k.type=k.buffer.dtype;k.offset=0;k.stride=0;k.divisor=0;k.state=1;a[h]=1}else f.getBuffer(l)?(k.buffer=f.getBuffer(l),k.size=k.buffer.dimension|0,k.normalized=!1,k.type=k.buffer.dtype,k.offset=0,k.stride=0,k.divisor=0,k.state=1):f.getBuffer(l.buffer)?(k.buffer=f.getBuffer(l.buffer),k.size=(+l.size|| +k.buffer.dimension)|0,k.normalized=!!l.normalized||!1,k.type="type"in l?Ja[l.type]:k.buffer.dtype,k.offset=(l.offset||0)|0,k.stride=(l.stride||0)|0,k.divisor=(l.divisor||0)|0,k.state=1):"x"in l&&(k.x=+l.x||0,k.y=+l.y||0,k.z=+l.z||0,k.w=+l.w||0,k.state=2)}for(p=0;pa&&(a=b.stats.uniformsCount)});return a},c.getMaxAttributesCount=function(){var a=0;t.forEach(function(b){b.stats.attributesCount>a&&(a=b.stats.attributesCount)});return a});return{clear:function(){var b=a.deleteShader.bind(a);T(r).forEach(b);r={};T(k).forEach(b); +k={};t.forEach(function(b){a.deleteProgram(b.program)});t.length=0;n={};c.shaderCount=0},program:function(b,d,e,f){var g=n[d];g||(g=n[d]={});var m=g[b];if(m&&(m.refCount++,!f))return m;var z=new q(d,b);c.shaderCount++;u(z,e,f);m||(g[b]=z);t.push(z);return O(z,{destroy:function(){z.refCount--;if(0>=z.refCount){a.deleteProgram(z.program);var b=t.indexOf(z);t.splice(b,1);c.shaderCount--}0>=g[z.vertId].refCount&&(a.deleteShader(k[z.vertId]),delete k[z.vertId],delete n[z.fragId][z.vertId]);Object.keys(n[z.fragId]).length|| +(a.deleteShader(r[z.fragId]),delete r[z.fragId],delete n[z.fragId])}})},restore:function(){r={};k={};for(var a=0;a>2),c=0;c>5]|=(a.charCodeAt(c/8)&255)<<24-c%32;var d=8*a.length;a=[1779033703,-1150833019,1013904242, +-1521486534,1359893119,-1694144372,528734635,1541459225];var c=Array(64),f,e,m,q,u,r,k,n,t,g,l;b[d>>5]|=128<<24-d%32;b[(d+64>>9<<4)+15]=d;for(n=0;nt;t++){if(16>t)c[t]=b[t+n];else{g=t;l=c[t-2];l=Y(l,17)^Y(l,19)^l>>>10;l=H(l,c[t-7]);var h;h=c[t-15];h=Y(h,7)^Y(h,18)^h>>>3;c[g]=H(H(l,h),c[t-16])}g=q;g=Y(g,6)^Y(g,11)^Y(g,25);g=H(H(H(H(k,g),q&u^~q&r),Vb[t]),c[t]);k=d;k=Y(k,2)^Y(k,13)^Y(k,22);l=H(k,d&f^d&e^f&e);k=r;r=u;u= +q;q=H(m,g);m=e;e=f;f=d;d=H(g,l)}a[0]=H(d,a[0]);a[1]=H(f,a[1]);a[2]=H(e,a[2]);a[3]=H(m,a[3]);a[4]=H(q,a[4]);a[5]=H(u,a[5]);a[6]=H(r,a[6]);a[7]=H(k,a[7])}b="";for(c=0;c<32*a.length;c+=8)b+=String.fromCharCode(a[c>>5]>>>24-c%32&255);return b}function Wb(a){for(var b="",c,d=0;d>>4&15)+"0123456789abcdef".charAt(c&15);return b}function Xb(a){for(var b="",c=-1,d,f;++c= +d&&56320<=f&&57343>=f&&(d=65536+((d&1023)<<10)+(f&1023),c++),127>=d?b+=String.fromCharCode(d):2047>=d?b+=String.fromCharCode(192|d>>>6&31,128|d&63):65535>=d?b+=String.fromCharCode(224|d>>>12&15,128|d>>>6&63,128|d&63):2097151>=d&&(b+=String.fromCharCode(240|d>>>18&7,128|d>>>12&63,128|d>>>6&63,128|d&63));return b}function Y(a,b){return a>>>b|a<<32-b}function H(a,b){var c=(a&65535)+(b&65535);return(a>>16)+(b>>16)+(c>>16)<<16|c&65535}function Aa(a){return Array.prototype.slice.call(a)}function Ba(a){return Aa(a).join("")} +function Yb(a){function b(){var a=[],b=[];return O(function(){a.push.apply(a,Aa(arguments))},{def:function(){var c="v"+f++;b.push(c);0"+b+"?"+e+".constant["+b+"]:0;"}).join(""),"}}else{", +"if(",x,"(",e,".buffer)){",k,"=",f,".createStream(",34962,",",e,".buffer);","}else{",k,"=",f,".getBuffer(",e,".buffer);","}",l,'="type" in ',e,"?",g.glTypes,"[",e,".type]:",k,".dtype;",F.normalized,"=!!",e,".normalized;");d("size");d("offset");d("stride");d("divisor");c("}}");c.exit("if(",F.isStream,"){",f,".destroyStream(",k,");","}");return F})});return g}function J(a){var b=a["static"],c=a.dynamic,d={};Object.keys(b).forEach(function(a){var c=b[a];d[a]=E(function(a,b){return"number"===typeof c|| +"boolean"===typeof c?""+c:a.link(c)})});Object.keys(c).forEach(function(a){var b=c[a];d[a]=L(b,function(a,c){return a.invoke(c,b)})});return d}function oa(a,b,d,e,f){function g(a){var b=l[a];b&&(m[a]=b)}var k=G(a,b),h=B(a,f),l=H(a,h,f),n=v(a,f),m=ba(a,f),q=D(a,f,k);g("viewport");g(p("scissor.box"));var t=0>1)",r],");")}function b(){c(u,".drawArraysInstancedANGLE(",[p,q,t,r],");")}m&&"null"!==m?y?a():(c("if(",m,"){"),a(),c("}else{"),b(),c("}")):b()}function g(){function a(){c(k+".drawElements("+[p,t,v,q+"<<(("+v+"-5121)>>1)"]+");")}function b(){c(k+".drawArrays("+[p,q,t]+");")}m&&"null"!== +m?y?a():(c("if(",m,"){"),a(),c("}else{"),b(),c("}")):b()}var h=a.shared,k=h.gl,l=h.draw,n=d.draw,m=function(){var e=n.elements,f=b;if(e){if(e.contextDep&&d.contextDynamic||e.propDep)f=c;e=e.append(a,f);n.elementsActive&&f("if("+e+")"+k+".bindBuffer(34963,"+e+".buffer.buffer);")}else e=f.def(),f(e,"=",l,".","elements",";","if(",e,"){",k,".bindBuffer(",34963,",",e,".buffer.buffer);}","else if(",h.vao,".currentVAO){",e,"=",a.shared.elements+".getElements("+h.vao,".currentVAO.elements);",ja?"":"if("+ +e+")"+k+".bindBuffer(34963,"+e+".buffer.buffer);","}");return e}(),p=e("primitive"),q=e("offset"),t=function(){var e=n.count,f=b;if(e){if(e.contextDep&&d.contextDynamic||e.propDep)f=c;e=e.append(a,f)}else e=f.def(l,".","count");return e}();if("number"===typeof t){if(0===t)return}else c("if(",t,"){"),c.exit("}");var r,u;sa&&(r=e("instances"),u=a.instancing);var v=m+".type",y=n.elements&&la(n.elements)&&!n.vaoActive;sa&&("number"!==typeof r||0<=r)?"string"===typeof r?(c("if(",r,">0){"),f(),c("}else if(", +r,"<0){"),g(),c("}")):f():g()}function xa(a,b,c,d,e){b=w();e=b.proc("body",e);sa&&(b.instancing=e.def(b.shared.extensions,".angle_instanced_arrays"));a(b,e,c,d);return b.compile().body}function da(a,b,c,d){Q(a,b);c.useVAO?c.drawVAO?b(a.shared.vao,".setVAO(",c.drawVAO.append(a,b),");"):b(a.shared.vao,".setVAO(",a.shared.vao,".targetVAO);"):(b(a.shared.vao,".setVAO(null);"),M(a,b,c,d.attributes,function(){return!0}));U(a,b,c,d.uniforms,function(){return!0},!1);Y(a,b,b,c)}function pa(a,b){var c=a.proc("draw", +1);Q(a,c);na(a,c,b.context);V(a,c,b.framebuffer);T(a,c,b);W(a,c,b.state);I(a,c,b,!1,!0);var d=b.shader.progVar.append(a,c);c(a.shared.gl,".useProgram(",d,".program);");if(b.shader.program)da(a,c,b,b.shader.program);else{c(a.shared.vao,".setVAO(null);");var e=a.global.def("{}"),f=c.def(d,".id"),g=c.def(e,"[",f,"]");c(a.cond(g).then(g,".call(this,a0);")["else"](g,"=",e,"[",f,"]=",a.link(function(c){return xa(da,a,b,c,1)}),"(",d,");",g,".call(this,a0);"))}0= +--this.refCount&&m(this)};f.profile&&(d.getTotalRenderbufferSize=function(){var a=0;Object.keys(k).forEach(function(b){a+=k[b].stats.size});return a});return{create:function(b,c){function g(b,c){var d=0,e=0,k=32854;"object"===typeof b&&b?("shape"in b?(e=b.shape,d=e[0]|0,e=e[1]|0):("radius"in b&&(d=e=b.radius|0),"width"in b&&(d=b.width|0),"height"in b&&(e=b.height|0)),"format"in b&&(k=q[b.format])):"number"===typeof b?(d=b|0,e="number"===typeof c?c|0:d):b||(d=e=1);if(d!==l.width||e!==l.height||k!== +l.format)return g.width=l.width=d,g.height=l.height=e,l.format=k,a.bindRenderbuffer(36161,l.renderbuffer),a.renderbufferStorage(36161,k,d,e),f.profile&&(l.stats.size=M[l.format]*l.width*l.height),g.format=u[l.format],g}var l=new e(a.createRenderbuffer());k[l.id]=l;d.renderbufferCount++;g(b,c);g.resize=function(b,c){var d=b|0,e=c|0||d;if(d===l.width&&e===l.height)return g;g.width=l.width=d;g.height=l.height=e;a.bindRenderbuffer(36161,l.renderbuffer);a.renderbufferStorage(36161,l.format,d,e);f.profile&& +(l.stats.size=M[l.format]*l.width*l.height);return g};g._reglType="renderbuffer";g._renderbuffer=l;f.profile&&(g.stats=l.stats);g.destroy=function(){l.decRef()};return g},clear:function(){T(k).forEach(m)},restore:function(){T(k).forEach(function(b){b.renderbuffer=a.createRenderbuffer();a.bindRenderbuffer(36161,b.renderbuffer);a.renderbufferStorage(36161,b.format,b.width,b.height)});a.bindRenderbuffer(36161,null)}}},Ya=[];Ya[6408]=4;Ya[6407]=3;var Ra=[];Ra[5121]=1;Ra[5126]=4;Ra[36193]=2;var Vb=[1116352408, +1899447441,-1245643825,-373957723,961987163,1508970993,-1841331548,-1424204075,-670586216,310598401,607225278,1426881987,1925078388,-2132889090,-1680079193,-1046744716,-459576895,-272742522,264347078,604807628,770255983,1249150122,1555081692,1996064986,-1740746414,-1473132947,-1341970488,-1084653625,-958395405,-710438585,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,-2117940946,-1838011259,-1564481375,-1474664885,-1035236496,-949202525,-778901479,-694614492,-200395387, +275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,-2067236844,-1933114872,-1866530822,-1538233109,-1090935817,-965641998],Ca=["x","y","z","w"],ac="blend.func blend.equation stencil.func stencil.opFront stencil.opBack sample.coverage viewport scissor.box polygonOffset.offset".split(" "),Ga={0:0,1:1,zero:0,one:1,"src color":768,"one minus src color":769,"src alpha":770,"one minus src alpha":771,"dst color":774,"one minus dst color":775, +"dst alpha":772,"one minus dst alpha":773,"constant color":32769,"one minus constant color":32770,"constant alpha":32771,"one minus constant alpha":32772,"src alpha saturate":776},$a={never:512,less:513,"<":513,equal:514,"=":514,"==":514,"===":514,lequal:515,"<=":515,greater:516,">":516,notequal:517,"!=":517,"!==":517,gequal:518,">=":518,always:519},Ta={0:0,zero:0,keep:7680,replace:7681,increment:7682,decrement:7683,"increment wrap":34055,"decrement wrap":34056,invert:5386},zb={cw:2304,ccw:2305}, +Ab=new K(!1,!1,!1,function(){}),dc=function(a,b){function c(){this.endQueryIndex=this.startQueryIndex=-1;this.sum=0;this.stats=null}function d(a,b,d){var e=m.pop()||new c;e.startQueryIndex=a;e.endQueryIndex=b;e.sum=0;e.stats=d;q.push(e)}if(!b.ext_disjoint_timer_query)return null;var f=[],e=[],m=[],q=[],u=[],r=[];return{beginQuery:function(a){var c=f.pop()||b.ext_disjoint_timer_query.createQueryEXT();b.ext_disjoint_timer_query.beginQueryEXT(35007,c);e.push(c);d(e.length-1,e.length,a)},endQuery:function(){b.ext_disjoint_timer_query.endQueryEXT(35007)}, +pushScopeStats:d,update:function(){var a,c;a=e.length;if(0!==a){r.length=Math.max(r.length,a+1);u.length=Math.max(u.length,a+1);u[0]=0;var d=r[0]=0;for(c=a=0;c=I.length&&d()}var c=Bb(I,a);I[c]=b}}}function r(){var a=W.viewport,b=W.scissor_box; +a[0]=a[1]=b[0]=b[1]=0;D.viewportWidth=D.framebufferWidth=D.drawingBufferWidth=a[2]=b[2]=g.drawingBufferWidth;D.viewportHeight=D.framebufferHeight=D.drawingBufferHeight=a[3]=b[3]=g.drawingBufferHeight}function k(){D.tick+=1;D.time=t();r();M.procs.poll()}function n(){L.refresh();r();M.procs.refresh();z&&z.update()}function t(){return(Cb()-E)/1E3}a=Hb(a);if(!a)return null;var g=a.gl,l=g.getContextAttributes();g.isContextLost();var h=Ib(g,a);if(!h)return null;var p=Eb(),y={vaoCount:0,bufferCount:0,elementsCount:0, +framebufferCount:0,shaderCount:0,textureCount:0,cubeCount:0,renderbufferCount:0,maxTextureUnits:0},C=a.cachedCode||{},w=h.extensions,z=dc(g,w),E=Cb(),B=g.drawingBufferWidth,H=g.drawingBufferHeight,D={tick:0,time:0,viewportWidth:B,viewportHeight:H,framebufferWidth:B,framebufferHeight:H,drawingBufferWidth:B,drawingBufferHeight:H,pixelRatio:a.pixelRatio},B={elements:null,primitive:4,count:-1,offset:0,instances:-1},v=bc(g,w),G=Jb(g,y,a,function(a){return A.destroyBuffer(a)}),K=Kb(g,w,G,y),A=Rb(g,w,v, +y,G,K,B),J=Sb(g,p,y,a),L=Nb(g,w,v,function(){M.procs.poll()},D,y,a),P=cc(g,w,v,y,a),V=Qb(g,w,v,L,P,y),M=Zb(g,p,w,v,G,K,L,V,{},A,J,B,D,z,C,a),p=Tb(g,V,M.procs.poll,D,l,w,v),W=M.next,Q=g.canvas,I=[],S=[],T=[],U=[a.onDestroy],R=null;Q&&(Q.addEventListener("webglcontextlost",f,!1),Q.addEventListener("webglcontextrestored",e,!1));var Y=V.setFBO=m({framebuffer:Z.define.call(null,1,"framebuffer")});n();l=O(m,{clear:function(a){if("framebuffer"in a)if(a.framebuffer&&"framebufferCube"===a.framebuffer_reglType)for(var b= +0;6>b;++b)Y(O({framebuffer:a.framebuffer.faces[b]},a),q);else Y(a,q);else q(null,a)},prop:Z.define.bind(null,1),context:Z.define.bind(null,2),"this":Z.define.bind(null,3),draw:m({}),buffer:function(a){return G.create(a,34962,!1,!1)},elements:function(a){return K.create(a,!1)},texture:L.create2D,cube:L.createCube,renderbuffer:P.create,framebuffer:V.create,framebufferCube:V.createCube,vao:A.createVAO,attributes:l,frame:u,on:function(a,b){var c;switch(a){case "frame":return u(b);case "lost":c=S;break; +case "restore":c=T;break;case "destroy":c=U}c.push(b);return{cancel:function(){for(var a=0;a 1) { - uniName = uniName.replace('[0]', '') - } - insertActiveInfo(uniforms, new ActiveInfo( - uniName, - stringStore.id(uniName), - gl.getUniformLocation(program, uniName), - info)) } } @@ -4929,6 +4932,298 @@ function wrapReadPixels ( return readPixels } +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined + * in FIPS 180-2 + * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for details. + * Also http://anmar.eu.org/projects/jssha2/ + */ + +/* + * Configurable variables. You may need to tweak these to be compatible with + * the server-side, but the defaults work in most cases. + */ +var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ +var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ + +/* + * These are the functions you'll usually want to call + * They take string arguments and return either hex or base-64 encoded strings + */ +function hex_sha256(s) { return rstr2hex(rstr_sha256(str2rstr_utf8(s))); } +/* + * Calculate the sha256 of a raw string + */ +function rstr_sha256(s) +{ + return binb2rstr(binb_sha256(rstr2binb(s), s.length * 8)); +} + +/* + * Calculate the HMAC-sha256 of a key and some data (raw strings) + */ +function rstr_hmac_sha256(key, data) +{ + var bkey = rstr2binb(key); + if(bkey.length > 16) bkey = binb_sha256(bkey, key.length * 8); + + var ipad = Array(16), opad = Array(16); + for(var i = 0; i < 16; i++) + { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = binb_sha256(ipad.concat(rstr2binb(data)), 512 + data.length * 8); + return binb2rstr(binb_sha256(opad.concat(hash), 512 + 256)); +} + +/* + * Convert a raw string to a hex string + */ +function rstr2hex(input) +{ + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var output = ""; + var x; + for(var i = 0; i < input.length; i++) + { + x = input.charCodeAt(i); + output += hex_tab.charAt((x >>> 4) & 0x0F) + + hex_tab.charAt( x & 0x0F); + } + return output; +} + +/* + * Convert a raw string to a base-64 string + */ +function rstr2b64(input) +{ + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var output = ""; + var len = input.length; + for(var i = 0; i < len; i += 3) + { + var triplet = (input.charCodeAt(i) << 16) + | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0) + | (i + 2 < len ? input.charCodeAt(i+2) : 0); + for(var j = 0; j < 4; j++) + { + if(i * 8 + j * 6 > input.length * 8) output += b64pad; + else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F); + } + } + return output; +} + +/* + * Convert a raw string to an arbitrary string encoding + */ +function rstr2any(input, encoding) +{ + var divisor = encoding.length; + var remainders = Array(); + var i, q, x, quotient; + + /* Convert to an array of 16-bit big-endian values, forming the dividend */ + var dividend = Array(Math.ceil(input.length / 2)); + for(i = 0; i < dividend.length; i++) + { + dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); + } + + /* + * Repeatedly perform a long division. The binary array forms the dividend, + * the length of the encoding is the divisor. Once computed, the quotient + * forms the dividend for the next step. We stop when the dividend is zero. + * All remainders are stored for later use. + */ + while(dividend.length > 0) + { + quotient = Array(); + x = 0; + for(i = 0; i < dividend.length; i++) + { + x = (x << 16) + dividend[i]; + q = Math.floor(x / divisor); + x -= q * divisor; + if(quotient.length > 0 || q > 0) + quotient[quotient.length] = q; + } + remainders[remainders.length] = x; + dividend = quotient; + } + + /* Convert the remainders to the output string */ + var output = ""; + for(i = remainders.length - 1; i >= 0; i--) + output += encoding.charAt(remainders[i]); + + /* Append leading zero equivalents */ + var full_length = Math.ceil(input.length * 8 / + (Math.log(encoding.length) / Math.log(2))) + for(i = output.length; i < full_length; i++) + output = encoding[0] + output; + + return output; +} + +/* + * Encode a string as utf-8. + * For efficiency, this assumes the input is valid utf-16. + */ +function str2rstr_utf8(input) +{ + var output = ""; + var i = -1; + var x, y; + + while(++i < input.length) + { + /* Decode utf-16 surrogate pairs */ + x = input.charCodeAt(i); + y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; + if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) + { + x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); + i++; + } + + /* Encode output as utf-8 */ + if(x <= 0x7F) + output += String.fromCharCode(x); + else if(x <= 0x7FF) + output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F), + 0x80 | ( x & 0x3F)); + else if(x <= 0xFFFF) + output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), + 0x80 | ((x >>> 6 ) & 0x3F), + 0x80 | ( x & 0x3F)); + else if(x <= 0x1FFFFF) + output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), + 0x80 | ((x >>> 12) & 0x3F), + 0x80 | ((x >>> 6 ) & 0x3F), + 0x80 | ( x & 0x3F)); + } + return output; +} + +/* + * Convert a raw string to an array of big-endian words + * Characters >255 have their high-byte silently ignored. + */ +function rstr2binb(input) +{ + var output = Array(input.length >> 2); + for(var i = 0; i < output.length; i++) + output[i] = 0; + for(var i = 0; i < input.length * 8; i += 8) + output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32); + return output; +} + +/* + * Convert an array of big-endian words to a string + */ +function binb2rstr(input) +{ + var output = ""; + for(var i = 0; i < input.length * 32; i += 8) + output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF); + return output; +} + +/* + * Main sha256 function, with its support functions + */ +function sha256_S (X, n) {return ( X >>> n ) | (X << (32 - n));} +function sha256_R (X, n) {return ( X >>> n );} +function sha256_Ch(x, y, z) {return ((x & y) ^ ((~x) & z));} +function sha256_Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));} +function sha256_Sigma0256(x) {return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));} +function sha256_Sigma1256(x) {return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));} +function sha256_Gamma0256(x) {return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));} +function sha256_Gamma1256(x) {return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));} +var sha256_K = new Array +( + 1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993, + -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987, + 1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522, + 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, + -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585, + 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, + 1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885, + -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344, + 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, + 1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872, + -1866530822, -1538233109, -1090935817, -965641998 +); + +function binb_sha256(m, l) +{ + var HASH = new Array(1779033703, -1150833019, 1013904242, -1521486534, + 1359893119, -1694144372, 528734635, 1541459225); + var W = new Array(64); + var a, b, c, d, e, f, g, h; + var i, j, T1, T2; + + /* append padding */ + m[l >> 5] |= 0x80 << (24 - l % 32); + m[((l + 64 >> 9) << 4) + 15] = l; + + for(i = 0; i < m.length; i += 16) + { + a = HASH[0]; + b = HASH[1]; + c = HASH[2]; + d = HASH[3]; + e = HASH[4]; + f = HASH[5]; + g = HASH[6]; + h = HASH[7]; + + for(j = 0; j < 64; j++) + { + if (j < 16) W[j] = m[j + i]; + else W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]), + sha256_Gamma0256(W[j - 15])), W[j - 16]); + + T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)), + sha256_K[j]), W[j]); + T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c)); + h = g; + g = f; + f = e; + e = safe_add(d, T1); + d = c; + c = b; + b = a; + a = safe_add(T1, T2); + } + + HASH[0] = safe_add(a, HASH[0]); + HASH[1] = safe_add(b, HASH[1]); + HASH[2] = safe_add(c, HASH[2]); + HASH[3] = safe_add(d, HASH[3]); + HASH[4] = safe_add(e, HASH[4]); + HASH[5] = safe_add(f, HASH[5]); + HASH[6] = safe_add(g, HASH[6]); + HASH[7] = safe_add(h, HASH[7]); + } + return HASH; +} + +function safe_add (x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + function slice (x) { return Array.prototype.slice.call(x) } @@ -4937,7 +5232,9 @@ function join (x) { return slice(x).join('') } -function createEnvironment () { +function createEnvironment (options) { + var cache = options && options.cache + // Unique variable id counter var varCounter = 0 @@ -4946,16 +5243,21 @@ function createEnvironment () { // the variable name which it is bound to var linkedNames = [] var linkedValues = [] - function link (value) { - for (var i = 0; i < linkedValues.length; ++i) { - if (linkedValues[i] === value) { - return linkedNames[i] + var isStable = [] + function link (value, options) { + var stable = options && options.stable + if (!stable) { + for (var i = 0; i < linkedValues.length; ++i) { + if (linkedValues[i] === value && !isStable[i]) { + return linkedNames[i] + } } } var name = 'g' + (varCounter++) linkedNames.push(name) linkedValues.push(value) + isStable.push(stable) return name } @@ -5095,7 +5397,21 @@ function createEnvironment () { .replace(/;/g, ';\n') .replace(/}/g, '}\n') .replace(/{/g, '{\n') + + var key + if (cache) { + key = hex_sha256(src); + + if (cache[key]) { + return cache[key].apply(null, linkedValues) + } + } + var proc = Function.apply(null, linkedNames.concat(src)) + + if (cache) { + cache[key] = proc + } return proc.apply(null, linkedValues) } @@ -5408,6 +5724,7 @@ function reglCore ( drawState, contextState, timer, + cachedCode, config) { var AttributeRecord = attributeState.Record @@ -5461,6 +5778,14 @@ function reglCore ( } GL_VARIABLES[name] = func } + + function hasVariableReference (exp) { + if (!isNaN(exp)) { + return false; + } + // strengthen this function if variable values can be non-(null/number) literals. + return true; + } // Dithering stateFlag(S_DITHER, GL_DITHER) @@ -5570,7 +5895,7 @@ function reglCore ( var drawCallCounter = 0 function createREGLEnvironment () { - var env = createEnvironment() + var env = createEnvironment({cache: cachedCode}) var link = env.link var global = env.global env.id = drawCallCounter++ @@ -7098,6 +7423,7 @@ function reglCore ( var CURRENT_VARS = env.current var CURRENT_STATE = shared.current var GL = shared.gl + var VALUE sortState(Object.keys(options)).forEach(function (param) { var defn = options[param] if (filter && !filter(defn)) { @@ -7107,17 +7433,17 @@ function reglCore ( if (GL_FLAGS[param]) { var flag = GL_FLAGS[param] if (isStatic(defn)) { - if (variable) { - scope(GL, '.enable(', flag, ');') - } else { - scope(GL, '.disable(', flag, ');') - } + VALUE = env.link(variable, {stable: true}) + scope(env.cond(VALUE) + .then(GL, '.enable(', flag, ');') + .else(GL, '.disable(', flag, ');')) + scope(CURRENT_STATE, '.', param, '=', VALUE, ';') } else { scope(env.cond(variable) .then(GL, '.enable(', flag, ');') .else(GL, '.disable(', flag, ');')) + scope(CURRENT_STATE, '.', param, '=', variable, ';') } - scope(CURRENT_STATE, '.', param, '=', variable, ';') } else if (isArrayLike(variable)) { var CURRENT = CURRENT_VARS[param] scope( @@ -7126,9 +7452,16 @@ function reglCore ( return CURRENT + '[' + i + ']=' + v }).join(';'), ';') } else { - scope( - GL, '.', GL_VARIABLES[param], '(', variable, ');', - CURRENT_STATE, '.', param, '=', variable, ';') + if (isStatic(defn)) { + VALUE = env.link(variable, {stable: true}) + scope( + GL, '.', GL_VARIABLES[param], '(', VALUE, ');', + CURRENT_STATE, '.', param, '=', VALUE, ';') + } else { + scope( + GL, '.', GL_VARIABLES[param], '(', variable, ');', + CURRENT_STATE, '.', param, '=', variable, ';') + } } }) } @@ -7366,25 +7699,12 @@ function reglCore ( var shared = env.shared var GL = shared.gl - var definedArrUniforms = {} var infix for (var i = 0; i < uniforms.length; ++i) { var uniform = uniforms[i] var name = uniform.name var type = uniform.info.type - var size = uniform.info.size var arg = args.uniforms[name] - if (size > 1) { - // either foo[n] or foos, avoid define both - if (!arg) { - continue - } - var arrUniformName = name.replace('[0]', '') - if (definedArrUniforms[arrUniformName]) { - continue - } - definedArrUniforms[arrUniformName] = 1 - } var UNIFORM = env.link(uniform) var LOCATION = UNIFORM + '.location' @@ -7420,11 +7740,7 @@ function reglCore ( } else { switch (type) { case GL_FLOAT$7: - if (size === 1) { - - } else { - - } + infix = '1f' break case GL_FLOAT_VEC2: @@ -7440,19 +7756,11 @@ function reglCore ( infix = '4f' break case GL_BOOL: - if (size === 1) { - - } else { - - } + infix = '1i' break case GL_INT$2: - if (size === 1) { - - } else { - - } + infix = '1i' break case GL_BOOL_VEC2: @@ -7480,15 +7788,8 @@ function reglCore ( infix = '4i' break } - if (size > 1) { - infix += 'v' - value = env.global.def('[' + - Array.prototype.slice.call(value) + ']') - } else { - value = isArrayLike(value) ? Array.prototype.slice.call(value) : value - } scope(GL, '.uniform', infix, '(', LOCATION, ',', - value, + isArrayLike(value) ? Array.prototype.slice.call(value) : value, ');') } continue @@ -7583,11 +7884,6 @@ function reglCore ( break } - if (infix.indexOf('Matrix') === -1 && size > 1) { - infix += 'v' - unroll = 1 - } - if (infix.charAt(0) === 'M') { scope(GL, '.uniform', infix, '(', LOCATION, ',') var matSize = Math.pow(type - GL_FLOAT_MAT2 + 2, 2) @@ -8113,10 +8409,18 @@ function reglCore ( var value = defn.append(env, scope) if (isArrayLike(value)) { value.forEach(function (v, i) { - scope.set(env.next[name], '[' + i + ']', v) + if (hasVariableReference(v)) { + scope.set(env.next[name], '[' + i + ']', v) + } else { + scope.set(env.next[name], '[' + i + ']', env.link(v, {stable: true})) + } }) } else { - scope.set(shared.next, '.' + name, value) + if (isStatic(defn)) { + scope.set(shared.next, '.' + name, env.link(value, {stable: true})) + } else { + scope.set(shared.next, '.' + name, value) + } } }) @@ -8128,17 +8432,28 @@ function reglCore ( if (!variable) { return } - scope.set(shared.draw, '.' + opt, '' + variable.append(env, scope)) + var VARIABLE = variable.append(env, scope) + if (hasVariableReference(VARIABLE)) { + scope.set(shared.draw, '.' + opt, VARIABLE) + } else { + scope.set(shared.draw, '.' + opt, env.link(VARIABLE), {stable: true}) + } }) Object.keys(args.uniforms).forEach(function (opt) { var value = args.uniforms[opt].append(env, scope) if (Array.isArray(value)) { - value = '[' + value.join() + ']' + value = '[' + value.map(function (v) { + if (hasVariableReference(v)) { + return v; + } else { + return env.link(v, {stable: true}) + } + }) + ']' } scope.set( shared.uniforms, - '[' + stringStore.id(opt) + ']', + '[' + env.link(stringStore.id(opt), {stable: true}) + ']', value) }) @@ -8151,13 +8466,23 @@ function reglCore ( }) if (args.scopeVAO) { - scope.set(shared.vao, '.targetVAO', args.scopeVAO.append(env, scope)) + var VARIABLE = args.scopeVAO.append(env, scope) + if (hasVariableReference(VARIABLE)) { + scope.set(shared.vao, '.targetVAO', VARIABLE) + } else { + scope.set(shared.vao, '.targetVAO', env.link(VARIABLE, {stable: true})) + } } function saveShader (name) { var shader = args.shader[name] if (shader) { - scope.set(shared.shader, '.' + name, shader.append(env, scope)) + var VARIABLE = shader.append(env, scope) + if (hasVariableReference(VARIABLE)) { + scope.set(shared.shader, '.' + name, VARIABLE) + } else { + scope.set(shared.shader, '.' + name, env.link(VARIABLE, {stable: true})) + } } } saveShader(S_VERT) @@ -8270,6 +8595,15 @@ function reglCore ( var args = parseArguments(options, attributes, uniforms, context, env) + if (args.shader.program) { + args.shader.program.attributes.sort(function (a, b) { + return a.name < b.name ? -1 : 1 + }) + args.shader.program.uniforms.sort(function (a, b) { + return a.name < b.name ? -1 : 1 + }) + } + emitDrawProc(env, args) emitScopeProc(env, args) emitBatchProc(env, args) @@ -8317,37 +8651,43 @@ function reglCore ( if (extensions.oes_vertex_array_object) { refresh(env.link(extensions.oes_vertex_array_object), '.bindVertexArrayOES(null);') } - for (var i = 0; i < limits.maxAttributes; ++i) { - var BINDING = refresh.def(shared.attributes, '[', i, ']') - var ifte = env.cond(BINDING, '.buffer') - ifte.then( - GL, '.enableVertexAttribArray(', i, ');', - GL, '.bindBuffer(', - GL_ARRAY_BUFFER$2, ',', - BINDING, '.buffer.buffer);', - GL, '.vertexAttribPointer(', - i, ',', - BINDING, '.size,', - BINDING, '.type,', - BINDING, '.normalized,', - BINDING, '.stride,', - BINDING, '.offset);' - ).else( - GL, '.disableVertexAttribArray(', i, ');', - GL, '.vertexAttrib4f(', - i, ',', - BINDING, '.x,', - BINDING, '.y,', - BINDING, '.z,', - BINDING, '.w);', - BINDING, '.buffer=null;') - refresh(ifte) - if (extInstancing) { - refresh( - INSTANCING, '.vertexAttribDivisorANGLE(', - i, ',', - BINDING, '.divisor);') - } + var BINDING = refresh.def(shared.attributes) + var TEMP_BINDING = refresh.def(0) + + var ifte = env.cond(TEMP_BINDING, '.buffer') + ifte.then( + GL, '.enableVertexAttribArray(i);', + GL, '.bindBuffer(', + GL_ARRAY_BUFFER$2, ',', + TEMP_BINDING, '.buffer.buffer);', + GL, '.vertexAttribPointer(i,', + TEMP_BINDING, '.size,', + TEMP_BINDING, '.type,', + TEMP_BINDING, '.normalized,', + TEMP_BINDING, '.stride,', + TEMP_BINDING, '.offset);' + ).else( + GL, '.disableVertexAttribArray(i);', + GL, '.vertexAttrib4f(i,', + TEMP_BINDING, '.x,', + TEMP_BINDING, '.y,', + TEMP_BINDING, '.z,', + TEMP_BINDING, '.w);', + TEMP_BINDING, '.buffer=null;') + var MAX_ATTRIBUTES = env.link(limits.maxAttributes, {stable: true}) + refresh( + 'for(var i=0;i<', MAX_ATTRIBUTES, ';++i){', + TEMP_BINDING, '=', BINDING, '[i];', + ifte, + '}' + ) + + if (extInstancing) { + refresh( + 'for(var i=0;i<', MAX_ATTRIBUTES, ';++i){', + INSTANCING, '.vertexAttribDivisorANGLE(i,', + BINDING, '[i].divisor);', + '}') } refresh( env.shared.vao, '.currentVAO=null;', @@ -8601,6 +8941,7 @@ function wrapREGL (args) { var stringStore = createStringStore() var stats$$1 = stats() + var cachedCode = config.cachedCode || {}; var extensions = extensionState.extensions var timer = createTimer(gl, extensions) @@ -8678,6 +9019,7 @@ function wrapREGL (args) { drawState, contextState, timer, + cachedCode, config) var readPixels = wrapReadPixels( gl, @@ -9094,6 +9436,16 @@ function wrapREGL (args) { } } + function getCachedCode() { + return cachedCode + } + + function preloadCachedCode(moreCache) { + Object.entries(moreCache).forEach(function (kv) { + cachedCode[kv[0]] = kv[1] + }) + } + var regl = extend(compileProcedure, { // Clear current FBO clear: clear, @@ -9154,7 +9506,11 @@ function wrapREGL (args) { now: now, // regl Statistics Information - stats: stats$$1 + stats: stats$$1, + + // cache generated code + getCachedCode: getCachedCode, + preloadCachedCode: preloadCachedCode }) config.onDone(null, regl) diff --git a/lib/core.js b/lib/core.js index f11d5c52..b661c29e 100644 --- a/lib/core.js +++ b/lib/core.js @@ -333,6 +333,7 @@ module.exports = function reglCore ( drawState, contextState, timer, + cachedCode, config) { var AttributeRecord = attributeState.Record @@ -386,6 +387,14 @@ module.exports = function reglCore ( } GL_VARIABLES[name] = func } + + function hasVariableReference (exp) { + if (!isNaN(exp)) { + return false; + } + // strengthen this function if variable values can be non-(null/number) literals. + return true; + } // Dithering stateFlag(S_DITHER, GL_DITHER) @@ -497,7 +506,7 @@ module.exports = function reglCore ( var drawCallCounter = 0 function createREGLEnvironment () { - var env = createEnvironment() + var env = createEnvironment({cache: cachedCode}) var link = env.link var global = env.global env.id = drawCallCounter++ @@ -2288,6 +2297,7 @@ module.exports = function reglCore ( var CURRENT_VARS = env.current var CURRENT_STATE = shared.current var GL = shared.gl + var VALUE sortState(Object.keys(options)).forEach(function (param) { var defn = options[param] if (filter && !filter(defn)) { @@ -2297,17 +2307,17 @@ module.exports = function reglCore ( if (GL_FLAGS[param]) { var flag = GL_FLAGS[param] if (isStatic(defn)) { - if (variable) { - scope(GL, '.enable(', flag, ');') - } else { - scope(GL, '.disable(', flag, ');') - } + VALUE = env.link(variable, {stable: true}) + scope(env.cond(VALUE) + .then(GL, '.enable(', flag, ');') + .else(GL, '.disable(', flag, ');')) + scope(CURRENT_STATE, '.', param, '=', VALUE, ';') } else { scope(env.cond(variable) .then(GL, '.enable(', flag, ');') .else(GL, '.disable(', flag, ');')) + scope(CURRENT_STATE, '.', param, '=', variable, ';') } - scope(CURRENT_STATE, '.', param, '=', variable, ';') } else if (isArrayLike(variable)) { var CURRENT = CURRENT_VARS[param] scope( @@ -2316,9 +2326,16 @@ module.exports = function reglCore ( return CURRENT + '[' + i + ']=' + v }).join(';'), ';') } else { - scope( - GL, '.', GL_VARIABLES[param], '(', variable, ');', - CURRENT_STATE, '.', param, '=', variable, ';') + if (isStatic(defn)) { + VALUE = env.link(variable, {stable: true}) + scope( + GL, '.', GL_VARIABLES[param], '(', VALUE, ');', + CURRENT_STATE, '.', param, '=', VALUE, ';') + } else { + scope( + GL, '.', GL_VARIABLES[param], '(', variable, ');', + CURRENT_STATE, '.', param, '=', variable, ';') + } } }) } @@ -3403,10 +3420,18 @@ module.exports = function reglCore ( var value = defn.append(env, scope) if (isArrayLike(value)) { value.forEach(function (v, i) { - scope.set(env.next[name], '[' + i + ']', v) + if (hasVariableReference(v)) { + scope.set(env.next[name], '[' + i + ']', v) + } else { + scope.set(env.next[name], '[' + i + ']', env.link(v, {stable: true})) + } }) } else { - scope.set(shared.next, '.' + name, value) + if (isStatic(defn)) { + scope.set(shared.next, '.' + name, env.link(value, {stable: true})) + } else { + scope.set(shared.next, '.' + name, value) + } } }) @@ -3418,17 +3443,28 @@ module.exports = function reglCore ( if (!variable) { return } - scope.set(shared.draw, '.' + opt, '' + variable.append(env, scope)) + var VARIABLE = variable.append(env, scope) + if (hasVariableReference(VARIABLE)) { + scope.set(shared.draw, '.' + opt, VARIABLE) + } else { + scope.set(shared.draw, '.' + opt, env.link(VARIABLE), {stable: true}) + } }) Object.keys(args.uniforms).forEach(function (opt) { var value = args.uniforms[opt].append(env, scope) if (Array.isArray(value)) { - value = '[' + value.join() + ']' + value = '[' + value.map(function (v) { + if (hasVariableReference(v)) { + return v; + } else { + return env.link(v, {stable: true}) + } + }) + ']' } scope.set( shared.uniforms, - '[' + stringStore.id(opt) + ']', + '[' + env.link(stringStore.id(opt), {stable: true}) + ']', value) }) @@ -3441,13 +3477,23 @@ module.exports = function reglCore ( }) if (args.scopeVAO) { - scope.set(shared.vao, '.targetVAO', args.scopeVAO.append(env, scope)) + var VARIABLE = args.scopeVAO.append(env, scope) + if (hasVariableReference(VARIABLE)) { + scope.set(shared.vao, '.targetVAO', VARIABLE) + } else { + scope.set(shared.vao, '.targetVAO', env.link(VARIABLE, {stable: true})) + } } function saveShader (name) { var shader = args.shader[name] if (shader) { - scope.set(shared.shader, '.' + name, shader.append(env, scope)) + var VARIABLE = shader.append(env, scope) + if (hasVariableReference(VARIABLE)) { + scope.set(shared.shader, '.' + name, VARIABLE) + } else { + scope.set(shared.shader, '.' + name, env.link(VARIABLE, {stable: true})) + } } } saveShader(S_VERT) @@ -3560,6 +3606,15 @@ module.exports = function reglCore ( var args = parseArguments(options, attributes, uniforms, context, env) + if (args.shader.program) { + args.shader.program.attributes.sort(function (a, b) { + return a.name < b.name ? -1 : 1 + }) + args.shader.program.uniforms.sort(function (a, b) { + return a.name < b.name ? -1 : 1 + }) + } + emitDrawProc(env, args) emitScopeProc(env, args) emitBatchProc(env, args) @@ -3607,37 +3662,43 @@ module.exports = function reglCore ( if (extensions.oes_vertex_array_object) { refresh(env.link(extensions.oes_vertex_array_object), '.bindVertexArrayOES(null);') } - for (var i = 0; i < limits.maxAttributes; ++i) { - var BINDING = refresh.def(shared.attributes, '[', i, ']') - var ifte = env.cond(BINDING, '.buffer') - ifte.then( - GL, '.enableVertexAttribArray(', i, ');', - GL, '.bindBuffer(', - GL_ARRAY_BUFFER, ',', - BINDING, '.buffer.buffer);', - GL, '.vertexAttribPointer(', - i, ',', - BINDING, '.size,', - BINDING, '.type,', - BINDING, '.normalized,', - BINDING, '.stride,', - BINDING, '.offset);' - ).else( - GL, '.disableVertexAttribArray(', i, ');', - GL, '.vertexAttrib4f(', - i, ',', - BINDING, '.x,', - BINDING, '.y,', - BINDING, '.z,', - BINDING, '.w);', - BINDING, '.buffer=null;') - refresh(ifte) - if (extInstancing) { - refresh( - INSTANCING, '.vertexAttribDivisorANGLE(', - i, ',', - BINDING, '.divisor);') - } + var BINDING = refresh.def(shared.attributes) + var TEMP_BINDING = refresh.def(0) + + var ifte = env.cond(TEMP_BINDING, '.buffer') + ifte.then( + GL, '.enableVertexAttribArray(i);', + GL, '.bindBuffer(', + GL_ARRAY_BUFFER, ',', + TEMP_BINDING, '.buffer.buffer);', + GL, '.vertexAttribPointer(i,', + TEMP_BINDING, '.size,', + TEMP_BINDING, '.type,', + TEMP_BINDING, '.normalized,', + TEMP_BINDING, '.stride,', + TEMP_BINDING, '.offset);' + ).else( + GL, '.disableVertexAttribArray(i);', + GL, '.vertexAttrib4f(i,', + TEMP_BINDING, '.x,', + TEMP_BINDING, '.y,', + TEMP_BINDING, '.z,', + TEMP_BINDING, '.w);', + TEMP_BINDING, '.buffer=null;') + var MAX_ATTRIBUTES = env.link(limits.maxAttributes, {stable: true}) + refresh( + 'for(var i=0;i<', MAX_ATTRIBUTES, ';++i){', + TEMP_BINDING, '=', BINDING, '[i];', + ifte, + '}' + ) + + if (extInstancing) { + refresh( + 'for(var i=0;i<', MAX_ATTRIBUTES, ';++i){', + INSTANCING, '.vertexAttribDivisorANGLE(i,', + BINDING, '[i].divisor);', + '}') } refresh( env.shared.vao, '.currentVAO=null;', diff --git a/lib/util/check.js b/lib/util/check.js index df374d12..369578b2 100644 --- a/lib/util/check.js +++ b/lib/util/check.js @@ -95,7 +95,8 @@ var constructorKeys = [ 'extensions', 'optionalExtensions', 'profile', - 'onDone' + 'onDone', + 'cachedCode' ] function checkConstructor (obj) { diff --git a/lib/util/codegen.js b/lib/util/codegen.js index 0b1d3b4c..a6bbe898 100644 --- a/lib/util/codegen.js +++ b/lib/util/codegen.js @@ -1,4 +1,5 @@ var extend = require('./extend') +var SHA256 = require("./sha256") function slice (x) { return Array.prototype.slice.call(x) @@ -8,7 +9,9 @@ function join (x) { return slice(x).join('') } -module.exports = function createEnvironment () { +module.exports = function createEnvironment (options) { + var cache = options && options.cache + // Unique variable id counter var varCounter = 0 @@ -17,16 +20,21 @@ module.exports = function createEnvironment () { // the variable name which it is bound to var linkedNames = [] var linkedValues = [] - function link (value) { - for (var i = 0; i < linkedValues.length; ++i) { - if (linkedValues[i] === value) { - return linkedNames[i] + var isStable = [] + function link (value, options) { + var stable = options && options.stable + if (!stable) { + for (var i = 0; i < linkedValues.length; ++i) { + if (linkedValues[i] === value && !isStable[i]) { + return linkedNames[i] + } } } var name = 'g' + (varCounter++) linkedNames.push(name) linkedValues.push(value) + isStable.push(stable) return name } @@ -166,7 +174,21 @@ module.exports = function createEnvironment () { .replace(/;/g, ';\n') .replace(/}/g, '}\n') .replace(/{/g, '{\n') + + var key + if (cache) { + key = SHA256(src); + + if (cache[key]) { + return cache[key].apply(null, linkedValues) + } + } + var proc = Function.apply(null, linkedNames.concat(src)) + + if (cache) { + cache[key] = proc + } return proc.apply(null, linkedValues) } diff --git a/lib/util/sha256.js b/lib/util/sha256.js new file mode 100644 index 00000000..0ff9ff81 --- /dev/null +++ b/lib/util/sha256.js @@ -0,0 +1,337 @@ +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined + * in FIPS 180-2 + * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for details. + * Also http://anmar.eu.org/projects/jssha2/ + */ + +/* + * Configurable variables. You may need to tweak these to be compatible with + * the server-side, but the defaults work in most cases. + */ +var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ +var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ + +/* + * These are the functions you'll usually want to call + * They take string arguments and return either hex or base-64 encoded strings + */ +function hex_sha256(s) { return rstr2hex(rstr_sha256(str2rstr_utf8(s))); } +function b64_sha256(s) { return rstr2b64(rstr_sha256(str2rstr_utf8(s))); } +function any_sha256(s, e) { return rstr2any(rstr_sha256(str2rstr_utf8(s)), e); } +function hex_hmac_sha256(k, d) + { return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); } +function b64_hmac_sha256(k, d) + { return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); } +function any_hmac_sha256(k, d, e) + { return rstr2any(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d)), e); } + +/* + * Perform a simple self-test to see if the VM is working + */ +function sha256_vm_test() +{ + return hex_sha256("abc").toLowerCase() == + "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"; +} + +/* + * Calculate the sha256 of a raw string + */ +function rstr_sha256(s) +{ + return binb2rstr(binb_sha256(rstr2binb(s), s.length * 8)); +} + +/* + * Calculate the HMAC-sha256 of a key and some data (raw strings) + */ +function rstr_hmac_sha256(key, data) +{ + var bkey = rstr2binb(key); + if(bkey.length > 16) bkey = binb_sha256(bkey, key.length * 8); + + var ipad = Array(16), opad = Array(16); + for(var i = 0; i < 16; i++) + { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + + var hash = binb_sha256(ipad.concat(rstr2binb(data)), 512 + data.length * 8); + return binb2rstr(binb_sha256(opad.concat(hash), 512 + 256)); +} + +/* + * Convert a raw string to a hex string + */ +function rstr2hex(input) +{ + var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var output = ""; + var x; + for(var i = 0; i < input.length; i++) + { + x = input.charCodeAt(i); + output += hex_tab.charAt((x >>> 4) & 0x0F) + + hex_tab.charAt( x & 0x0F); + } + return output; +} + +/* + * Convert a raw string to a base-64 string + */ +function rstr2b64(input) +{ + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var output = ""; + var len = input.length; + for(var i = 0; i < len; i += 3) + { + var triplet = (input.charCodeAt(i) << 16) + | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0) + | (i + 2 < len ? input.charCodeAt(i+2) : 0); + for(var j = 0; j < 4; j++) + { + if(i * 8 + j * 6 > input.length * 8) output += b64pad; + else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F); + } + } + return output; +} + +/* + * Convert a raw string to an arbitrary string encoding + */ +function rstr2any(input, encoding) +{ + var divisor = encoding.length; + var remainders = Array(); + var i, q, x, quotient; + + /* Convert to an array of 16-bit big-endian values, forming the dividend */ + var dividend = Array(Math.ceil(input.length / 2)); + for(i = 0; i < dividend.length; i++) + { + dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); + } + + /* + * Repeatedly perform a long division. The binary array forms the dividend, + * the length of the encoding is the divisor. Once computed, the quotient + * forms the dividend for the next step. We stop when the dividend is zero. + * All remainders are stored for later use. + */ + while(dividend.length > 0) + { + quotient = Array(); + x = 0; + for(i = 0; i < dividend.length; i++) + { + x = (x << 16) + dividend[i]; + q = Math.floor(x / divisor); + x -= q * divisor; + if(quotient.length > 0 || q > 0) + quotient[quotient.length] = q; + } + remainders[remainders.length] = x; + dividend = quotient; + } + + /* Convert the remainders to the output string */ + var output = ""; + for(i = remainders.length - 1; i >= 0; i--) + output += encoding.charAt(remainders[i]); + + /* Append leading zero equivalents */ + var full_length = Math.ceil(input.length * 8 / + (Math.log(encoding.length) / Math.log(2))) + for(i = output.length; i < full_length; i++) + output = encoding[0] + output; + + return output; +} + +/* + * Encode a string as utf-8. + * For efficiency, this assumes the input is valid utf-16. + */ +function str2rstr_utf8(input) +{ + var output = ""; + var i = -1; + var x, y; + + while(++i < input.length) + { + /* Decode utf-16 surrogate pairs */ + x = input.charCodeAt(i); + y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; + if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) + { + x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); + i++; + } + + /* Encode output as utf-8 */ + if(x <= 0x7F) + output += String.fromCharCode(x); + else if(x <= 0x7FF) + output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F), + 0x80 | ( x & 0x3F)); + else if(x <= 0xFFFF) + output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), + 0x80 | ((x >>> 6 ) & 0x3F), + 0x80 | ( x & 0x3F)); + else if(x <= 0x1FFFFF) + output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), + 0x80 | ((x >>> 12) & 0x3F), + 0x80 | ((x >>> 6 ) & 0x3F), + 0x80 | ( x & 0x3F)); + } + return output; +} + +/* + * Encode a string as utf-16 + */ +function str2rstr_utf16le(input) +{ + var output = ""; + for(var i = 0; i < input.length; i++) + output += String.fromCharCode( input.charCodeAt(i) & 0xFF, + (input.charCodeAt(i) >>> 8) & 0xFF); + return output; +} + +function str2rstr_utf16be(input) +{ + var output = ""; + for(var i = 0; i < input.length; i++) + output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, + input.charCodeAt(i) & 0xFF); + return output; +} + +/* + * Convert a raw string to an array of big-endian words + * Characters >255 have their high-byte silently ignored. + */ +function rstr2binb(input) +{ + var output = Array(input.length >> 2); + for(var i = 0; i < output.length; i++) + output[i] = 0; + for(var i = 0; i < input.length * 8; i += 8) + output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32); + return output; +} + +/* + * Convert an array of big-endian words to a string + */ +function binb2rstr(input) +{ + var output = ""; + for(var i = 0; i < input.length * 32; i += 8) + output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF); + return output; +} + +/* + * Main sha256 function, with its support functions + */ +function sha256_S (X, n) {return ( X >>> n ) | (X << (32 - n));} +function sha256_R (X, n) {return ( X >>> n );} +function sha256_Ch(x, y, z) {return ((x & y) ^ ((~x) & z));} +function sha256_Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));} +function sha256_Sigma0256(x) {return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));} +function sha256_Sigma1256(x) {return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));} +function sha256_Gamma0256(x) {return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));} +function sha256_Gamma1256(x) {return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));} +function sha256_Sigma0512(x) {return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39));} +function sha256_Sigma1512(x) {return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41));} +function sha256_Gamma0512(x) {return (sha256_S(x, 1) ^ sha256_S(x, 8) ^ sha256_R(x, 7));} +function sha256_Gamma1512(x) {return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6));} + +var sha256_K = new Array +( + 1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993, + -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987, + 1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522, + 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, + -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585, + 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, + 1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885, + -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344, + 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, + 1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872, + -1866530822, -1538233109, -1090935817, -965641998 +); + +function binb_sha256(m, l) +{ + var HASH = new Array(1779033703, -1150833019, 1013904242, -1521486534, + 1359893119, -1694144372, 528734635, 1541459225); + var W = new Array(64); + var a, b, c, d, e, f, g, h; + var i, j, T1, T2; + + /* append padding */ + m[l >> 5] |= 0x80 << (24 - l % 32); + m[((l + 64 >> 9) << 4) + 15] = l; + + for(i = 0; i < m.length; i += 16) + { + a = HASH[0]; + b = HASH[1]; + c = HASH[2]; + d = HASH[3]; + e = HASH[4]; + f = HASH[5]; + g = HASH[6]; + h = HASH[7]; + + for(j = 0; j < 64; j++) + { + if (j < 16) W[j] = m[j + i]; + else W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]), + sha256_Gamma0256(W[j - 15])), W[j - 16]); + + T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)), + sha256_K[j]), W[j]); + T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c)); + h = g; + g = f; + f = e; + e = safe_add(d, T1); + d = c; + c = b; + b = a; + a = safe_add(T1, T2); + } + + HASH[0] = safe_add(a, HASH[0]); + HASH[1] = safe_add(b, HASH[1]); + HASH[2] = safe_add(c, HASH[2]); + HASH[3] = safe_add(d, HASH[3]); + HASH[4] = safe_add(e, HASH[4]); + HASH[5] = safe_add(f, HASH[5]); + HASH[6] = safe_add(g, HASH[6]); + HASH[7] = safe_add(h, HASH[7]); + } + return HASH; +} + +function safe_add (x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + +module.exports = hex_sha256; \ No newline at end of file diff --git a/lib/webgl.js b/lib/webgl.js index a1e922d5..078a7cf6 100644 --- a/lib/webgl.js +++ b/lib/webgl.js @@ -119,6 +119,7 @@ module.exports = function parseArgs (args_) { var optionalExtensions = [] var pixelRatio = (typeof window === 'undefined' ? 1 : window.devicePixelRatio) var profile = false + var cachedCode = {} var onDone = function (err) { if (err) { check.raise(err) @@ -169,6 +170,12 @@ module.exports = function parseArgs (args_) { pixelRatio = +args.pixelRatio check(pixelRatio > 0, 'invalid pixel ratio') } + if ('cachedCode' in args) { + check.type( + args.cachedCode, 'object', + 'invalid cachedCode') + cachedCode = args.cachedCode + } } } else { check.raise('invalid arguments to regl') @@ -213,6 +220,7 @@ module.exports = function parseArgs (args_) { optionalExtensions: optionalExtensions, pixelRatio: pixelRatio, profile: profile, + cachedCode: cachedCode, onDone: onDone, onDestroy: onDestroy } diff --git a/package-lock.json b/package-lock.json index 0a5bc0bf..8bfab6bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { - "name": "regl", - "version": "2.1.0", + "name": "@plotly/regl", + "version": "2.1.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index a8479668..8ee428e3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "regl", - "version": "2.1.0", + "name": "@plotly/regl", + "version": "2.1.1", "description": "regl is a fast functional WebGL framework.", "main": "dist/regl.js", "types": "dist/regl.d.ts", diff --git a/regl.js b/regl.js index c20b7355..ede96583 100644 --- a/regl.js +++ b/regl.js @@ -58,6 +58,7 @@ module.exports = function wrapREGL (args) { var stringStore = createStringStore() var stats = createStats() + var cachedCode = config.cachedCode || {}; var extensions = extensionState.extensions var timer = createTimer(gl, extensions) @@ -135,6 +136,7 @@ module.exports = function wrapREGL (args) { drawState, contextState, timer, + cachedCode, config) var readPixels = wrapRead( gl, @@ -553,6 +555,16 @@ module.exports = function wrapREGL (args) { } } + function getCachedCode() { + return cachedCode + } + + function preloadCachedCode(moreCache) { + Object.entries(moreCache).forEach(function (kv) { + cachedCode[kv[0]] = kv[1] + }) + } + var regl = extend(compileProcedure, { // Clear current FBO clear: clear, @@ -613,7 +625,11 @@ module.exports = function wrapREGL (args) { now: now, // regl Statistics Information - stats: stats + stats: stats, + + // cache generated code + getCachedCode: getCachedCode, + preloadCachedCode: preloadCachedCode }) config.onDone(null, regl)