Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@luma.gl/webgl2-polyfill

Package Overview
Dependencies
Maintainers
8
Versions
61
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@luma.gl/webgl2-polyfill - npm Package Compare versions

Comparing version 7.0.0-alpha.14 to 7.0.0-alpha.15

dist/es5/assert.js

313

dist/es5/polyfill-context.js

@@ -10,184 +10,27 @@ "use strict";

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _assert = _interopRequireDefault(require("./assert"));
var _polyfillGetParameter = require("./polyfill-get-parameter");
var _polyfillTable = require("./polyfill-table");
var _WEBGL_CONTEXT_POLYFI;
function polyfillContext(gl) {
gl.luma = gl.luma || {};
initializeExtensions(gl);
function assert(condition, message) {
if (!condition) {
throw new Error(message || 'luma.gl: assertion failed.');
if (!gl.luma.polyfilled) {
installPolyfills(gl, _polyfillTable.WEBGL2_CONTEXT_POLYFILLS);
installOverrides(gl, {
target: gl.luma,
target2: gl
});
gl.luma.polyfilled = true;
}
return gl;
}
var OES_vertex_array_object = 'OES_vertex_array_object';
var ANGLE_instanced_arrays = 'ANGLE_instanced_arrays';
var WEBGL_draw_buffers = 'WEBGL_draw_buffers';
var EXT_disjoint_timer_query = 'EXT_disjoint_timer_query';
var EXT_texture_filter_anisotropic = 'EXT_texture_filter_anisotropic';
var ERR_VAO_NOT_SUPPORTED = 'VertexArray requires WebGL2 or OES_vertex_array_object extension'; // Return true if WebGL2 context
var global_ = typeof global !== 'undefined' ? global : window;
global_.polyfillContext = polyfillContext;
function isWebGL2(gl) {
return gl && 32874 === 32874;
} // Return object with webgl2 flag and an extension
function getExtensionData(gl, extension) {
return {
webgl2: isWebGL2(gl),
ext: gl.getExtension(extension)
};
} // function mapExtensionConstant(gl, constant) {
// switch (constant) {
// case ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES: return GL.FRAGMENT_SHADER_DERIVATIVE_HINT;
// }
// }
var WEBGL_CONTEXT_POLYFILLS = (_WEBGL_CONTEXT_POLYFI = {}, (0, _defineProperty2.default)(_WEBGL_CONTEXT_POLYFI, OES_vertex_array_object, {
meta: {
suffix: 'OES'
},
// NEW METHODS
createVertexArray: function createVertexArray() {
assert(false, ERR_VAO_NOT_SUPPORTED);
},
deleteVertexArray: function deleteVertexArray() {},
bindVertexArray: function bindVertexArray() {},
isVertexArray: function isVertexArray() {
return false;
}
}), (0, _defineProperty2.default)(_WEBGL_CONTEXT_POLYFI, ANGLE_instanced_arrays, {
meta: {
suffix: 'ANGLE' // constants: {
// VERTEX_ATTRIB_ARRAY_DIVISOR: 'VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE'
// }
},
vertexAttribDivisor: function vertexAttribDivisor(location, divisor) {
// Accept divisor 0 even if instancing is not supported (0 = no instancing)
assert(divisor === 0, 'WebGL instanced rendering not supported');
},
drawElementsInstanced: function drawElementsInstanced() {},
drawArraysInstanced: function drawArraysInstanced() {}
}), (0, _defineProperty2.default)(_WEBGL_CONTEXT_POLYFI, WEBGL_draw_buffers, {
meta: {
suffix: 'WEBGL'
},
drawBuffers: function drawBuffers() {
assert(false);
}
}), (0, _defineProperty2.default)(_WEBGL_CONTEXT_POLYFI, EXT_disjoint_timer_query, {
meta: {
suffix: 'EXT'
},
// WebGL1: Polyfills the WebGL2 Query API
createQuery: function createQuery() {
assert(false);
},
deleteQuery: function deleteQuery() {
assert(false);
},
beginQuery: function beginQuery() {
assert(false);
},
endQuery: function endQuery() {},
getQuery: function getQuery(handle, pname) {
return this.getQueryObject(handle, pname);
},
// The WebGL1 extension uses getQueryObject rather then getQueryParameter
getQueryParameter: function getQueryParameter(handle, pname) {
return this.getQueryObject(handle, pname);
},
getQueryObject: function getQueryObject() {}
}), (0, _defineProperty2.default)(_WEBGL_CONTEXT_POLYFI, "OVERRIDES", {
// Ensure readBuffer is a no-op
readBuffer: function readBuffer(gl, originalFunc, attachment) {
if (isWebGL2(gl)) {
originalFunc(attachment);
} else {// assert(attachment !== GL_COLOR_ATTACHMENT0 && attachment !== GL_FRONT);
}
},
// Override for getVertexAttrib that returns sane values for non-WebGL1 constants
getVertexAttrib: function getVertexAttrib(gl, originalFunc, location, pname) {
// const gl = this; // eslint-disable-line
var _getExtensionData = getExtensionData(gl, ANGLE_instanced_arrays),
webgl2 = _getExtensionData.webgl2,
ext = _getExtensionData.ext;
var result;
switch (pname) {
// WebGL1 attributes will never be integer
case 35069:
result = !webgl2 ? false : undefined;
break;
// if instancing is not available, return 0 meaning divisor has not been set
case 35070:
result = !webgl2 && !ext ? 0 : undefined;
break;
default:
}
return result !== undefined ? result : originalFunc(location, pname);
},
// Handle transform feedback and uniform block queries in WebGL1
getProgramParameter: function getProgramParameter(gl, originalFunc, program, pname) {
if (!isWebGL2(gl)) {
switch (pname) {
case 35967:
return 35981;
case 35971:
return 0;
case 35382:
return 0;
default:
}
}
return originalFunc(program, pname);
},
getInternalformatParameter: function getInternalformatParameter(gl, originalFunc, target, format, pname) {
if (!isWebGL2(gl)) {
switch (pname) {
case 32937:
return new Int32Array([0]);
default:
}
}
return gl.getInternalformatParameter(target, format, pname);
},
getTexParameter: function getTexParameter(gl, originalFunc, target, pname) {
switch (pname) {
case 34046:
var extensions = gl.luma.extensions;
var ext = extensions[EXT_texture_filter_anisotropic];
pname = ext && ext.TEXTURE_MAX_ANISOTROPY_EXT || 34046;
break;
default:
}
return originalFunc(target, pname);
},
getParameter: _polyfillGetParameter.getParameterPolyfill,
hint: function hint(gl, originalFunc, pname, value) {
// TODO - handle GL.FRAGMENT_SHADER_DERIVATIVE_HINT:
// switch (pname) {
// case GL.FRAGMENT_SHADER_DERIVATIVE_HINT:
// }
return originalFunc(pname, value);
}
}), _WEBGL_CONTEXT_POLYFI);
function initializeExtensions(gl) {
gl.luma.extensions = {}; // `getSupportedExtensions` can return null when context is lost.
gl.luma.extensions = {};
var EXTENSIONS = gl.getSupportedExtensions() || [];

@@ -217,11 +60,58 @@ var _iteratorNormalCompletion = true;

}
} // Polyfills a single WebGL extension into the `target` object
}
function installOverrides(gl, _ref) {
var target = _ref.target,
target2 = _ref.target2;
Object.keys(_polyfillTable.WEBGL2_CONTEXT_OVERRIDES).forEach(function (key) {
if (typeof _polyfillTable.WEBGL2_CONTEXT_OVERRIDES[key] === 'function') {
var originalFunc = gl[key] ? gl[key].bind(gl) : function () {};
function polyfillExtension(gl, _ref) {
var extension = _ref.extension,
target = _ref.target,
target2 = _ref.target2;
var defaults = WEBGL_CONTEXT_POLYFILLS[extension];
assert(defaults);
var polyfill = _polyfillTable.WEBGL2_CONTEXT_OVERRIDES[key].bind(null, gl, originalFunc);
target[key] = polyfill;
target2[key] = polyfill;
}
});
}
function installPolyfills(gl, polyfills) {
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = Object.getOwnPropertyNames(polyfills)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var extension = _step2.value;
if (extension !== 'overrides') {
polyfillExtension(gl, {
extension: extension,
target: gl.luma,
target2: gl
});
}
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
function polyfillExtension(gl, _ref2) {
var extension = _ref2.extension,
target = _ref2.target,
target2 = _ref2.target2;
var defaults = _polyfillTable.WEBGL2_CONTEXT_POLYFILLS[extension];
(0, _assert.default)(defaults);
var _defaults$meta = defaults.meta,

@@ -232,10 +122,11 @@ meta = _defaults$meta === void 0 ? {} : _defaults$meta;

var ext = gl.getExtension(extension);
Object.keys(defaults).forEach(function (key) {
var _arr = Object.keys(defaults);
var _loop = function _loop() {
var key = _arr[_i];
var extKey = "".concat(key).concat(suffix);
var polyfill = null;
if (key === 'meta') {// ignore
} else if (typeof gl[key] === 'function') {// WebGL2 implementation is already
} else if (ext && typeof ext[extKey] === 'function') {
// pick extension implemenentation,if available
if (key === 'meta') {} else if (typeof gl[key] === 'function') {} else if (ext && typeof ext[extKey] === 'function') {
polyfill = function polyfill() {

@@ -245,3 +136,2 @@ return ext[extKey].apply(ext, arguments);

} else if (typeof defaults[key] === 'function') {
// pick the mock implementation, if no implementation was detected
polyfill = defaults[key].bind(target);

@@ -254,51 +144,8 @@ }

}
});
} // Install simple overrides (mostly get* functions)
};
function installOverrides(gl, _ref2) {
var target = _ref2.target,
target2 = _ref2.target2;
var OVERRIDES = WEBGL_CONTEXT_POLYFILLS.OVERRIDES;
Object.keys(OVERRIDES).forEach(function (key) {
if (typeof OVERRIDES[key] === 'function') {
// install an override, if no implementation was detected
var originalFunc = gl[key] ? gl[key].bind(gl) : function () {};
var polyfill = OVERRIDES[key].bind(null, gl, originalFunc);
target[key] = polyfill;
target2[key] = polyfill;
}
});
} // Registers polyfill or mock functions for all known extensions
function polyfillContext(gl) {
// polyfillVertexArrayObject(WebGLRenderingContext, gl);
gl.luma = gl.luma || {};
initializeExtensions(gl);
if (!gl.luma.polyfilled) {
Object.getOwnPropertyNames(WEBGL_CONTEXT_POLYFILLS).forEach(function (extension) {
if (extension !== 'overrides') {
polyfillExtension(gl, {
extension: extension,
target: gl.luma,
target2: gl
});
}
});
installOverrides(gl, {
target: gl.luma,
target2: gl
});
gl.luma.polyfilled = true;
for (var _i = 0; _i < _arr.length; _i++) {
_loop();
}
return gl;
}
/* global window, global */
var global_ = typeof global !== 'undefined' ? global : window;
global_.polyfillContext = polyfillContext;
//# sourceMappingURL=polyfill-context.js.map

@@ -1,4 +0,3 @@

// Installs polyfills to support a subset of WebGL2 APIs on WebGL1 contexts
export { default as polyfillContext } from './polyfill-context';
export { default } from './polyfill-context';
//# sourceMappingURL=index.js.map

@@ -1,203 +0,23 @@

// WebGL1/WebGL2 extension polyfill support
//
// Provides a function that creates polyfills for WebGL2 functions based
// on available extensions and installs them on a supplied target (could be
// the WebGLContext or its prototype, or a separate object).
//
// This is intended to be a stand-alone file with minimal dependencies,
// easy to reuse or repurpose in other projects.
import assert from './assert';
import { WEBGL2_CONTEXT_POLYFILLS, WEBGL2_CONTEXT_OVERRIDES } from './polyfill-table';
export default function polyfillContext(gl) {
gl.luma = gl.luma || {};
initializeExtensions(gl);
/* eslint-disable camelcase, brace-style */
import { getParameterPolyfill } from './polyfill-get-parameter';
if (!gl.luma.polyfilled) {
installPolyfills(gl, WEBGL2_CONTEXT_POLYFILLS);
installOverrides(gl, {
target: gl.luma,
target2: gl
});
gl.luma.polyfilled = true;
}
function assert(condition, message) {
if (!condition) {
throw new Error(message || 'luma.gl: assertion failed.');
}
return gl;
}
const global_ = typeof global !== 'undefined' ? global : window;
global_.polyfillContext = polyfillContext;
const OES_vertex_array_object = 'OES_vertex_array_object';
const ANGLE_instanced_arrays = 'ANGLE_instanced_arrays';
const WEBGL_draw_buffers = 'WEBGL_draw_buffers';
const EXT_disjoint_timer_query = 'EXT_disjoint_timer_query';
const EXT_texture_filter_anisotropic = 'EXT_texture_filter_anisotropic';
const ERR_VAO_NOT_SUPPORTED = 'VertexArray requires WebGL2 or OES_vertex_array_object extension'; // Return true if WebGL2 context
function isWebGL2(gl) {
return gl && 32874 === 32874;
} // Return object with webgl2 flag and an extension
function getExtensionData(gl, extension) {
return {
webgl2: isWebGL2(gl),
ext: gl.getExtension(extension)
};
} // function mapExtensionConstant(gl, constant) {
// switch (constant) {
// case ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES: return GL.FRAGMENT_SHADER_DERIVATIVE_HINT;
// }
// }
const WEBGL_CONTEXT_POLYFILLS = {
// POLYFILL TABLE
[OES_vertex_array_object]: {
meta: {
suffix: 'OES'
},
// NEW METHODS
createVertexArray: () => {
assert(false, ERR_VAO_NOT_SUPPORTED);
},
deleteVertexArray: () => {},
bindVertexArray: () => {},
isVertexArray: () => false
},
[ANGLE_instanced_arrays]: {
meta: {
suffix: 'ANGLE' // constants: {
// VERTEX_ATTRIB_ARRAY_DIVISOR: 'VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE'
// }
},
vertexAttribDivisor(location, divisor) {
// Accept divisor 0 even if instancing is not supported (0 = no instancing)
assert(divisor === 0, 'WebGL instanced rendering not supported');
},
drawElementsInstanced: () => {},
drawArraysInstanced: () => {}
},
[WEBGL_draw_buffers]: {
meta: {
suffix: 'WEBGL'
},
drawBuffers: () => {
assert(false);
}
},
[EXT_disjoint_timer_query]: {
meta: {
suffix: 'EXT'
},
// WebGL1: Polyfills the WebGL2 Query API
createQuery: () => {
assert(false);
},
deleteQuery: () => {
assert(false);
},
beginQuery: () => {
assert(false);
},
endQuery: () => {},
getQuery(handle, pname) {
return this.getQueryObject(handle, pname);
},
// The WebGL1 extension uses getQueryObject rather then getQueryParameter
getQueryParameter(handle, pname) {
return this.getQueryObject(handle, pname);
},
getQueryObject: () => {}
},
OVERRIDES: {
// Ensure readBuffer is a no-op
readBuffer: (gl, originalFunc, attachment) => {
if (isWebGL2(gl)) {
originalFunc(attachment);
} else {// assert(attachment !== GL_COLOR_ATTACHMENT0 && attachment !== GL_FRONT);
}
},
// Override for getVertexAttrib that returns sane values for non-WebGL1 constants
getVertexAttrib: (gl, originalFunc, location, pname) => {
// const gl = this; // eslint-disable-line
const _getExtensionData = getExtensionData(gl, ANGLE_instanced_arrays),
webgl2 = _getExtensionData.webgl2,
ext = _getExtensionData.ext;
let result;
switch (pname) {
// WebGL1 attributes will never be integer
case 35069:
result = !webgl2 ? false : undefined;
break;
// if instancing is not available, return 0 meaning divisor has not been set
case 35070:
result = !webgl2 && !ext ? 0 : undefined;
break;
default:
}
return result !== undefined ? result : originalFunc(location, pname);
},
// Handle transform feedback and uniform block queries in WebGL1
getProgramParameter: (gl, originalFunc, program, pname) => {
if (!isWebGL2(gl)) {
switch (pname) {
case 35967:
return 35981;
case 35971:
return 0;
case 35382:
return 0;
default:
}
}
return originalFunc(program, pname);
},
getInternalformatParameter: (gl, originalFunc, target, format, pname) => {
if (!isWebGL2(gl)) {
switch (pname) {
case 32937:
return new Int32Array([0]);
default:
}
}
return gl.getInternalformatParameter(target, format, pname);
},
getTexParameter(gl, originalFunc, target, pname) {
switch (pname) {
case 34046:
const extensions = gl.luma.extensions;
const ext = extensions[EXT_texture_filter_anisotropic];
pname = ext && ext.TEXTURE_MAX_ANISOTROPY_EXT || 34046;
break;
default:
}
return originalFunc(target, pname);
},
getParameter: getParameterPolyfill,
hint(gl, originalFunc, pname, value) {
// TODO - handle GL.FRAGMENT_SHADER_DERIVATIVE_HINT:
// switch (pname) {
// case GL.FRAGMENT_SHADER_DERIVATIVE_HINT:
// }
return originalFunc(pname, value);
}
}
};
function initializeExtensions(gl) {
gl.luma.extensions = {}; // `getSupportedExtensions` can return null when context is lost.
gl.luma.extensions = {};
const EXTENSIONS = gl.getSupportedExtensions() || [];

@@ -208,5 +28,30 @@

}
} // Polyfills a single WebGL extension into the `target` object
}
function installOverrides(gl, {
target,
target2
}) {
Object.keys(WEBGL2_CONTEXT_OVERRIDES).forEach(key => {
if (typeof WEBGL2_CONTEXT_OVERRIDES[key] === 'function') {
const originalFunc = gl[key] ? gl[key].bind(gl) : () => {};
const polyfill = WEBGL2_CONTEXT_OVERRIDES[key].bind(null, gl, originalFunc);
target[key] = polyfill;
target2[key] = polyfill;
}
});
}
function installPolyfills(gl, polyfills) {
for (const extension of Object.getOwnPropertyNames(polyfills)) {
if (extension !== 'overrides') {
polyfillExtension(gl, {
extension,
target: gl.luma,
target2: gl
});
}
}
}
function polyfillExtension(gl, {

@@ -217,3 +62,3 @@ extension,

}) {
const defaults = WEBGL_CONTEXT_POLYFILLS[extension];
const defaults = WEBGL2_CONTEXT_POLYFILLS[extension];
assert(defaults);

@@ -225,13 +70,10 @@ const _defaults$meta = defaults.meta,

const ext = gl.getExtension(extension);
Object.keys(defaults).forEach(key => {
for (const key of Object.keys(defaults)) {
const extKey = `${key}${suffix}`;
let polyfill = null;
if (key === 'meta') {// ignore
} else if (typeof gl[key] === 'function') {// WebGL2 implementation is already
} else if (ext && typeof ext[extKey] === 'function') {
// pick extension implemenentation,if available
if (key === 'meta') {} else if (typeof gl[key] === 'function') {} else if (ext && typeof ext[extKey] === 'function') {
polyfill = (...args) => ext[extKey](...args);
} else if (typeof defaults[key] === 'function') {
// pick the mock implementation, if no implementation was detected
polyfill = defaults[key].bind(target);

@@ -244,51 +86,4 @@ }

}
});
} // Install simple overrides (mostly get* functions)
function installOverrides(gl, {
target,
target2
}) {
const OVERRIDES = WEBGL_CONTEXT_POLYFILLS.OVERRIDES;
Object.keys(OVERRIDES).forEach(key => {
if (typeof OVERRIDES[key] === 'function') {
// install an override, if no implementation was detected
const originalFunc = gl[key] ? gl[key].bind(gl) : () => {};
const polyfill = OVERRIDES[key].bind(null, gl, originalFunc);
target[key] = polyfill;
target2[key] = polyfill;
}
});
} // Registers polyfill or mock functions for all known extensions
export default function polyfillContext(gl) {
// polyfillVertexArrayObject(WebGLRenderingContext, gl);
gl.luma = gl.luma || {};
initializeExtensions(gl);
if (!gl.luma.polyfilled) {
Object.getOwnPropertyNames(WEBGL_CONTEXT_POLYFILLS).forEach(extension => {
if (extension !== 'overrides') {
polyfillExtension(gl, {
extension,
target: gl.luma,
target2: gl
});
}
});
installOverrides(gl, {
target: gl.luma,
target2: gl
});
gl.luma.polyfilled = true;
}
return gl;
}
/* global window, global */
const global_ = typeof global !== 'undefined' ? global : window;
global_.polyfillContext = polyfillContext;
//# sourceMappingURL=polyfill-context.js.map

@@ -1,4 +0,3 @@

// Installs polyfills to support a subset of WebGL2 APIs on WebGL1 contexts
export { default as polyfillContext } from './polyfill-context';
export { default } from './polyfill-context';
//# sourceMappingURL=index.js.map

@@ -1,193 +0,23 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import assert from './assert';
import { WEBGL2_CONTEXT_POLYFILLS, WEBGL2_CONTEXT_OVERRIDES } from './polyfill-table';
export default function polyfillContext(gl) {
gl.luma = gl.luma || {};
initializeExtensions(gl);
var _WEBGL_CONTEXT_POLYFI;
if (!gl.luma.polyfilled) {
installPolyfills(gl, WEBGL2_CONTEXT_POLYFILLS);
installOverrides(gl, {
target: gl.luma,
target2: gl
});
gl.luma.polyfilled = true;
}
// WebGL1/WebGL2 extension polyfill support
//
// Provides a function that creates polyfills for WebGL2 functions based
// on available extensions and installs them on a supplied target (could be
// the WebGLContext or its prototype, or a separate object).
//
// This is intended to be a stand-alone file with minimal dependencies,
// easy to reuse or repurpose in other projects.
/* eslint-disable camelcase, brace-style */
import { getParameterPolyfill } from './polyfill-get-parameter';
function assert(condition, message) {
if (!condition) {
throw new Error(message || 'luma.gl: assertion failed.');
}
return gl;
}
var global_ = typeof global !== 'undefined' ? global : window;
global_.polyfillContext = polyfillContext;
var OES_vertex_array_object = 'OES_vertex_array_object';
var ANGLE_instanced_arrays = 'ANGLE_instanced_arrays';
var WEBGL_draw_buffers = 'WEBGL_draw_buffers';
var EXT_disjoint_timer_query = 'EXT_disjoint_timer_query';
var EXT_texture_filter_anisotropic = 'EXT_texture_filter_anisotropic';
var ERR_VAO_NOT_SUPPORTED = 'VertexArray requires WebGL2 or OES_vertex_array_object extension'; // Return true if WebGL2 context
function isWebGL2(gl) {
return gl && 32874 === 32874;
} // Return object with webgl2 flag and an extension
function getExtensionData(gl, extension) {
return {
webgl2: isWebGL2(gl),
ext: gl.getExtension(extension)
};
} // function mapExtensionConstant(gl, constant) {
// switch (constant) {
// case ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES: return GL.FRAGMENT_SHADER_DERIVATIVE_HINT;
// }
// }
var WEBGL_CONTEXT_POLYFILLS = (_WEBGL_CONTEXT_POLYFI = {}, _defineProperty(_WEBGL_CONTEXT_POLYFI, OES_vertex_array_object, {
meta: {
suffix: 'OES'
},
// NEW METHODS
createVertexArray: function createVertexArray() {
assert(false, ERR_VAO_NOT_SUPPORTED);
},
deleteVertexArray: function deleteVertexArray() {},
bindVertexArray: function bindVertexArray() {},
isVertexArray: function isVertexArray() {
return false;
}
}), _defineProperty(_WEBGL_CONTEXT_POLYFI, ANGLE_instanced_arrays, {
meta: {
suffix: 'ANGLE' // constants: {
// VERTEX_ATTRIB_ARRAY_DIVISOR: 'VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE'
// }
},
vertexAttribDivisor: function vertexAttribDivisor(location, divisor) {
// Accept divisor 0 even if instancing is not supported (0 = no instancing)
assert(divisor === 0, 'WebGL instanced rendering not supported');
},
drawElementsInstanced: function drawElementsInstanced() {},
drawArraysInstanced: function drawArraysInstanced() {}
}), _defineProperty(_WEBGL_CONTEXT_POLYFI, WEBGL_draw_buffers, {
meta: {
suffix: 'WEBGL'
},
drawBuffers: function drawBuffers() {
assert(false);
}
}), _defineProperty(_WEBGL_CONTEXT_POLYFI, EXT_disjoint_timer_query, {
meta: {
suffix: 'EXT'
},
// WebGL1: Polyfills the WebGL2 Query API
createQuery: function createQuery() {
assert(false);
},
deleteQuery: function deleteQuery() {
assert(false);
},
beginQuery: function beginQuery() {
assert(false);
},
endQuery: function endQuery() {},
getQuery: function getQuery(handle, pname) {
return this.getQueryObject(handle, pname);
},
// The WebGL1 extension uses getQueryObject rather then getQueryParameter
getQueryParameter: function getQueryParameter(handle, pname) {
return this.getQueryObject(handle, pname);
},
getQueryObject: function getQueryObject() {}
}), _defineProperty(_WEBGL_CONTEXT_POLYFI, "OVERRIDES", {
// Ensure readBuffer is a no-op
readBuffer: function readBuffer(gl, originalFunc, attachment) {
if (isWebGL2(gl)) {
originalFunc(attachment);
} else {// assert(attachment !== GL_COLOR_ATTACHMENT0 && attachment !== GL_FRONT);
}
},
// Override for getVertexAttrib that returns sane values for non-WebGL1 constants
getVertexAttrib: function getVertexAttrib(gl, originalFunc, location, pname) {
// const gl = this; // eslint-disable-line
var _getExtensionData = getExtensionData(gl, ANGLE_instanced_arrays),
webgl2 = _getExtensionData.webgl2,
ext = _getExtensionData.ext;
var result;
switch (pname) {
// WebGL1 attributes will never be integer
case 35069:
result = !webgl2 ? false : undefined;
break;
// if instancing is not available, return 0 meaning divisor has not been set
case 35070:
result = !webgl2 && !ext ? 0 : undefined;
break;
default:
}
return result !== undefined ? result : originalFunc(location, pname);
},
// Handle transform feedback and uniform block queries in WebGL1
getProgramParameter: function getProgramParameter(gl, originalFunc, program, pname) {
if (!isWebGL2(gl)) {
switch (pname) {
case 35967:
return 35981;
case 35971:
return 0;
case 35382:
return 0;
default:
}
}
return originalFunc(program, pname);
},
getInternalformatParameter: function getInternalformatParameter(gl, originalFunc, target, format, pname) {
if (!isWebGL2(gl)) {
switch (pname) {
case 32937:
return new Int32Array([0]);
default:
}
}
return gl.getInternalformatParameter(target, format, pname);
},
getTexParameter: function getTexParameter(gl, originalFunc, target, pname) {
switch (pname) {
case 34046:
var extensions = gl.luma.extensions;
var ext = extensions[EXT_texture_filter_anisotropic];
pname = ext && ext.TEXTURE_MAX_ANISOTROPY_EXT || 34046;
break;
default:
}
return originalFunc(target, pname);
},
getParameter: getParameterPolyfill,
hint: function hint(gl, originalFunc, pname, value) {
// TODO - handle GL.FRAGMENT_SHADER_DERIVATIVE_HINT:
// switch (pname) {
// case GL.FRAGMENT_SHADER_DERIVATIVE_HINT:
// }
return originalFunc(pname, value);
}
}), _WEBGL_CONTEXT_POLYFI);
function initializeExtensions(gl) {
gl.luma.extensions = {}; // `getSupportedExtensions` can return null when context is lost.
gl.luma.extensions = {};
var EXTENSIONS = gl.getSupportedExtensions() || [];

@@ -217,10 +47,55 @@ var _iteratorNormalCompletion = true;

}
} // Polyfills a single WebGL extension into the `target` object
}
function installOverrides(gl, _ref) {
var target = _ref.target,
target2 = _ref.target2;
Object.keys(WEBGL2_CONTEXT_OVERRIDES).forEach(function (key) {
if (typeof WEBGL2_CONTEXT_OVERRIDES[key] === 'function') {
var originalFunc = gl[key] ? gl[key].bind(gl) : function () {};
var polyfill = WEBGL2_CONTEXT_OVERRIDES[key].bind(null, gl, originalFunc);
target[key] = polyfill;
target2[key] = polyfill;
}
});
}
function polyfillExtension(gl, _ref) {
var extension = _ref.extension,
target = _ref.target,
target2 = _ref.target2;
var defaults = WEBGL_CONTEXT_POLYFILLS[extension];
function installPolyfills(gl, polyfills) {
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = Object.getOwnPropertyNames(polyfills)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var extension = _step2.value;
if (extension !== 'overrides') {
polyfillExtension(gl, {
extension: extension,
target: gl.luma,
target2: gl
});
}
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
function polyfillExtension(gl, _ref2) {
var extension = _ref2.extension,
target = _ref2.target,
target2 = _ref2.target2;
var defaults = WEBGL2_CONTEXT_POLYFILLS[extension];
assert(defaults);

@@ -232,10 +107,11 @@ var _defaults$meta = defaults.meta,

var ext = gl.getExtension(extension);
Object.keys(defaults).forEach(function (key) {
var _arr = Object.keys(defaults);
var _loop = function _loop() {
var key = _arr[_i];
var extKey = "".concat(key).concat(suffix);
var polyfill = null;
if (key === 'meta') {// ignore
} else if (typeof gl[key] === 'function') {// WebGL2 implementation is already
} else if (ext && typeof ext[extKey] === 'function') {
// pick extension implemenentation,if available
if (key === 'meta') {} else if (typeof gl[key] === 'function') {} else if (ext && typeof ext[extKey] === 'function') {
polyfill = function polyfill() {

@@ -245,3 +121,2 @@ return ext[extKey].apply(ext, arguments);

} else if (typeof defaults[key] === 'function') {
// pick the mock implementation, if no implementation was detected
polyfill = defaults[key].bind(target);

@@ -254,50 +129,8 @@ }

}
});
} // Install simple overrides (mostly get* functions)
};
function installOverrides(gl, _ref2) {
var target = _ref2.target,
target2 = _ref2.target2;
var OVERRIDES = WEBGL_CONTEXT_POLYFILLS.OVERRIDES;
Object.keys(OVERRIDES).forEach(function (key) {
if (typeof OVERRIDES[key] === 'function') {
// install an override, if no implementation was detected
var originalFunc = gl[key] ? gl[key].bind(gl) : function () {};
var polyfill = OVERRIDES[key].bind(null, gl, originalFunc);
target[key] = polyfill;
target2[key] = polyfill;
}
});
} // Registers polyfill or mock functions for all known extensions
export default function polyfillContext(gl) {
// polyfillVertexArrayObject(WebGLRenderingContext, gl);
gl.luma = gl.luma || {};
initializeExtensions(gl);
if (!gl.luma.polyfilled) {
Object.getOwnPropertyNames(WEBGL_CONTEXT_POLYFILLS).forEach(function (extension) {
if (extension !== 'overrides') {
polyfillExtension(gl, {
extension: extension,
target: gl.luma,
target2: gl
});
}
});
installOverrides(gl, {
target: gl.luma,
target2: gl
});
gl.luma.polyfilled = true;
for (var _i = 0; _i < _arr.length; _i++) {
_loop();
}
return gl;
}
/* global window, global */
var global_ = typeof global !== 'undefined' ? global : window;
global_.polyfillContext = polyfillContext;
//# sourceMappingURL=polyfill-context.js.map
{
"name": "@luma.gl/webgl2-polyfill",
"version": "7.0.0-alpha.14",
"version": "7.0.0-alpha.15",
"description": "WebGL2 API Polyfills for WebGL1 WebGLRenderingContext",

@@ -32,3 +32,3 @@ "license": "MIT",

"@babel/runtime": "^7.0.0",
"@luma.gl/constants": "^7.0.0-alpha.6"
"@luma.gl/constants": "^7.0.0-alpha.15"
},

@@ -35,0 +35,0 @@ "devDependencies": {

# @luma.gl/webgl2-polyfill
This moduls installs a partial set of polyfills for WebGL1 contexts, making them more API compatible with WebGL2.
This module installs a partial set of polyfills for WebGL1 contexts, making them more API compatible with WebGL2.

@@ -8,4 +8,5 @@ * It adds WebGL2 methods to the WebGL1 context, and simply forwards the calls to WebGL1 extensions.

This way applications can work directly with the WebGL2 API even when using WebGL1 with extensions. It removes conditional code from applications and prepares application code bases for WebGL2.
This way applications can use the WebGL2 API even when using WebGL1 with extensions. While you will still have to check that the extensions you need are available, using the WebGL2 API removes multiple code paths from your application and prepares your code base for WebGL2.
## Usage

@@ -25,4 +26,48 @@

## Functions
### polyfillContext(gl : WebGLRenderingContext) : WebGLRenderingContext
Installs WebGL2 polyfills on the supplied context.
Returns: the supplied context, with additional methods added (unless it was already a `WebGL2RenderingContext` in which case those methods were already present).
Note: Can be called multiple times and will only install the polyfills once.
## Polyfill List
After `polyfillContext` has been called on a `WebGLRenderingContext`, the following `WebGL2RenderingContext` methods will be available on the context:
| Polyfilled Method | Uses Extension | Fallback if no extension |
| --- | --- | --- |
| `gl.createVertexArray()` | `OES_vertex_array_object` | throws error |
| `gl.deleteVertexArray()` | | ignored |
| `gl.bindVertexArray()` | | ignored |
| `gl.isVertexArray()` | | ignored |
| Polyfilled Method | Uses Extension | Fallback if no extension |
| --- | --- | --- |
| `gl.vertexAttribDivisor()` | `ANGLE_instanced_arrays` | throws error |
| `gl.drawElementsInstanced()` | | ignored |
| `gl.drawArraysInstanced()` | | ignored |
| Polyfilled Method | Uses Extension | Fallback if no extension |
| --- | --- | --- |
| `gl.drawBuffers()` | `WEBGL_draw_buffers` | throws error |
| Polyfilled Method | Uses Extension | Fallback if no extension |
| --- | --- | --- |
| `gl.createQuery()` | `EXT_disjoint_timer_query` | throws error |
| `gl.deleteQuery()` | | ignored |
| `gl.beginQuery()` | | ignored |
| `gl.endQuery()` | | ignored |
| `gl.getQuery()` | | ignored |
| `gl.getQueryParameter()` | | ignored |
## Remarks
* This a helper module for [luma.gl](http://luma.gl), but is designed to be independently usable in other projects.
* This module was originally created as a helper for [luma.gl](http://luma.gl), but is designed to be independently usable in other projects. It has no dependencies and makes no assumptions about other modules being available.

@@ -11,170 +11,24 @@ // WebGL1/WebGL2 extension polyfill support

/* eslint-disable camelcase, brace-style */
import GL from '@luma.gl/constants';
import {getParameterPolyfill} from './polyfill-get-parameter';
import assert from './assert';
function assert(condition, message) {
if (!condition) {
throw new Error(message || 'luma.gl: assertion failed.');
import {WEBGL2_CONTEXT_POLYFILLS, WEBGL2_CONTEXT_OVERRIDES} from './polyfill-table';
// Registers extensions, polyfills or mock functions for extensions in the polyfills list
// TODO - remove use of name `luma`.
export default function polyfillContext(gl) {
gl.luma = gl.luma || {};
initializeExtensions(gl);
if (!gl.luma.polyfilled) {
installPolyfills(gl, WEBGL2_CONTEXT_POLYFILLS);
installOverrides(gl, {target: gl.luma, target2: gl});
gl.luma.polyfilled = true;
}
return gl;
}
const OES_vertex_array_object = 'OES_vertex_array_object';
const ANGLE_instanced_arrays = 'ANGLE_instanced_arrays';
const WEBGL_draw_buffers = 'WEBGL_draw_buffers';
const EXT_disjoint_timer_query = 'EXT_disjoint_timer_query';
const EXT_texture_filter_anisotropic = 'EXT_texture_filter_anisotropic';
// TODO - is this still required?
/* global window, global */
const global_ = typeof global !== 'undefined' ? global : window;
global_.polyfillContext = polyfillContext;
const ERR_VAO_NOT_SUPPORTED = 'VertexArray requires WebGL2 or OES_vertex_array_object extension';
// Return true if WebGL2 context
function isWebGL2(gl) {
return gl && gl.TEXTURE_BINDING_3D === GL.TEXTURE_BINDING_3D;
}
// Return object with webgl2 flag and an extension
function getExtensionData(gl, extension) {
return {
webgl2: isWebGL2(gl),
ext: gl.getExtension(extension)
};
}
// function mapExtensionConstant(gl, constant) {
// switch (constant) {
// case ext.FRAGMENT_SHADER_DERIVATIVE_HINT_OES: return GL.FRAGMENT_SHADER_DERIVATIVE_HINT;
// }
// }
const WEBGL_CONTEXT_POLYFILLS = {
// POLYFILL TABLE
[OES_vertex_array_object]: {
meta: {suffix: 'OES'},
// NEW METHODS
createVertexArray: () => {
assert(false, ERR_VAO_NOT_SUPPORTED);
},
deleteVertexArray: () => {},
bindVertexArray: () => {},
isVertexArray: () => false
},
[ANGLE_instanced_arrays]: {
meta: {
suffix: 'ANGLE'
// constants: {
// VERTEX_ATTRIB_ARRAY_DIVISOR: 'VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE'
// }
},
vertexAttribDivisor(location, divisor) {
// Accept divisor 0 even if instancing is not supported (0 = no instancing)
assert(divisor === 0, 'WebGL instanced rendering not supported');
},
drawElementsInstanced: () => {},
drawArraysInstanced: () => {}
},
[WEBGL_draw_buffers]: {
meta: {
suffix: 'WEBGL'
},
drawBuffers: () => {
assert(false);
}
},
[EXT_disjoint_timer_query]: {
meta: {suffix: 'EXT'},
// WebGL1: Polyfills the WebGL2 Query API
createQuery: () => {
assert(false);
},
deleteQuery: () => {
assert(false);
},
beginQuery: () => {
assert(false);
},
endQuery: () => {},
getQuery(handle, pname) {
return this.getQueryObject(handle, pname);
},
// The WebGL1 extension uses getQueryObject rather then getQueryParameter
getQueryParameter(handle, pname) {
return this.getQueryObject(handle, pname);
},
getQueryObject: () => {}
},
OVERRIDES: {
// Ensure readBuffer is a no-op
readBuffer: (gl, originalFunc, attachment) => {
if (isWebGL2(gl)) {
originalFunc(attachment);
} else {
// assert(attachment !== GL_COLOR_ATTACHMENT0 && attachment !== GL_FRONT);
}
},
// Override for getVertexAttrib that returns sane values for non-WebGL1 constants
getVertexAttrib: (gl, originalFunc, location, pname) => {
// const gl = this; // eslint-disable-line
const {webgl2, ext} = getExtensionData(gl, ANGLE_instanced_arrays);
let result;
switch (pname) {
// WebGL1 attributes will never be integer
case GL.VERTEX_ATTRIB_ARRAY_INTEGER:
result = !webgl2 ? false : undefined;
break;
// if instancing is not available, return 0 meaning divisor has not been set
case GL.VERTEX_ATTRIB_ARRAY_DIVISOR:
result = !webgl2 && !ext ? 0 : undefined;
break;
default:
}
return result !== undefined ? result : originalFunc(location, pname);
},
// Handle transform feedback and uniform block queries in WebGL1
getProgramParameter: (gl, originalFunc, program, pname) => {
if (!isWebGL2(gl)) {
switch (pname) {
case GL.TRANSFORM_FEEDBACK_BUFFER_MODE:
return GL.SEPARATE_ATTRIBS;
case GL.TRANSFORM_FEEDBACK_VARYINGS:
return 0;
case GL.ACTIVE_UNIFORM_BLOCKS:
return 0;
default:
}
}
return originalFunc(program, pname);
},
getInternalformatParameter: (gl, originalFunc, target, format, pname) => {
if (!isWebGL2(gl)) {
switch (pname) {
case GL.SAMPLES:
return new Int32Array([0]);
default:
}
}
return gl.getInternalformatParameter(target, format, pname);
},
getTexParameter(gl, originalFunc, target, pname) {
switch (pname) {
case GL.TEXTURE_MAX_ANISOTROPY_EXT:
const {extensions} = gl.luma;
const ext = extensions[EXT_texture_filter_anisotropic];
pname = (ext && ext.TEXTURE_MAX_ANISOTROPY_EXT) || GL.TEXTURE_MAX_ANISOTROPY_EXT;
break;
default:
}
return originalFunc(target, pname);
},
getParameter: getParameterPolyfill,
hint(gl, originalFunc, pname, value) {
// TODO - handle GL.FRAGMENT_SHADER_DERIVATIVE_HINT:
// switch (pname) {
// case GL.FRAGMENT_SHADER_DERIVATIVE_HINT:
// }
return originalFunc(pname, value);
}
}
};
function initializeExtensions(gl) {

@@ -189,5 +43,26 @@ gl.luma.extensions = {};

// Install simple overrides (mostly get* functions)
function installOverrides(gl, {target, target2}) {
Object.keys(WEBGL2_CONTEXT_OVERRIDES).forEach(key => {
if (typeof WEBGL2_CONTEXT_OVERRIDES[key] === 'function') {
// install an override, if no implementation was detected
const originalFunc = gl[key] ? gl[key].bind(gl) : () => {};
const polyfill = WEBGL2_CONTEXT_OVERRIDES[key].bind(null, gl, originalFunc);
target[key] = polyfill;
target2[key] = polyfill;
}
});
}
function installPolyfills(gl, polyfills) {
for (const extension of Object.getOwnPropertyNames(polyfills)) {
if (extension !== 'overrides') {
polyfillExtension(gl, {extension, target: gl.luma, target2: gl});
}
}
}
// Polyfills a single WebGL extension into the `target` object
function polyfillExtension(gl, {extension, target, target2}) {
const defaults = WEBGL_CONTEXT_POLYFILLS[extension];
const defaults = WEBGL2_CONTEXT_POLYFILLS[extension];
assert(defaults);

@@ -200,3 +75,3 @@

Object.keys(defaults).forEach(key => {
for (const key of Object.keys(defaults)) {
const extKey = `${key}${suffix}`;

@@ -221,38 +96,3 @@

}
});
}
// Install simple overrides (mostly get* functions)
function installOverrides(gl, {target, target2}) {
const {OVERRIDES} = WEBGL_CONTEXT_POLYFILLS;
Object.keys(OVERRIDES).forEach(key => {
if (typeof OVERRIDES[key] === 'function') {
// install an override, if no implementation was detected
const originalFunc = gl[key] ? gl[key].bind(gl) : () => {};
const polyfill = OVERRIDES[key].bind(null, gl, originalFunc);
target[key] = polyfill;
target2[key] = polyfill;
}
});
}
// Registers polyfill or mock functions for all known extensions
export default function polyfillContext(gl) {
// polyfillVertexArrayObject(WebGLRenderingContext, gl);
gl.luma = gl.luma || {};
initializeExtensions(gl);
if (!gl.luma.polyfilled) {
Object.getOwnPropertyNames(WEBGL_CONTEXT_POLYFILLS).forEach(extension => {
if (extension !== 'overrides') {
polyfillExtension(gl, {extension, target: gl.luma, target2: gl});
}
});
installOverrides(gl, {target: gl.luma, target2: gl});
gl.luma.polyfilled = true;
}
return gl;
}
/* global window, global */
const global_ = typeof global !== 'undefined' ? global : window;
global_.polyfillContext = polyfillContext;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc