@luma.gl/gltools
Version:
WebGL2 API Polyfills for WebGL1 WebGLRenderingContext
274 lines (221 loc) • 8.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createGLContext = createGLContext;
exports.getContextDebugInfo = getContextDebugInfo;
exports.instrumentGLContext = instrumentGLContext;
exports.resizeGLContext = resizeGLContext;
var _env = require("@probe.gl/env");
var _trackContextState = require("../state-tracker/track-context-state");
var _log2 = require("../utils/log");
var _assert = require("../utils/assert");
var _devicePixels = require("../utils/device-pixels");
var _webglChecks = require("../utils/webgl-checks");
var isBrowser = (0, _env.isBrowser)();
var isPage = isBrowser && typeof document !== 'undefined';
var CONTEXT_DEFAULTS = {
webgl2: true,
webgl1: true,
throwOnError: true,
manageState: true,
canvas: null,
debug: false,
width: 800,
height: 600
};
function createGLContext() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
(0, _assert.assert)(isBrowser, "createGLContext only available in the browser.\nCreate your own headless context or use 'createHeadlessContext' from @luma.gl/test-utils");
options = Object.assign({}, CONTEXT_DEFAULTS, options);
var _options = options,
width = _options.width,
height = _options.height;
function onError(message) {
if (options.throwOnError) {
throw new Error(message);
}
console.error(message);
return null;
}
options.onError = onError;
var gl;
var _options2 = options,
canvas = _options2.canvas;
var targetCanvas = getCanvas({
canvas: canvas,
width: width,
height: height,
onError: onError
});
gl = createBrowserContext(targetCanvas, options);
if (!gl) {
return null;
}
gl = instrumentGLContext(gl, options);
logInfo(gl);
return gl;
}
function instrumentGLContext(gl) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (!gl || gl._instrumented) {
return gl;
}
gl._version = gl._version || getVersion(gl);
gl.luma = gl.luma || {};
gl.luma.canvasSizeInfo = gl.luma.canvasSizeInfo || {};
options = Object.assign({}, CONTEXT_DEFAULTS, options);
var _options3 = options,
manageState = _options3.manageState,
debug = _options3.debug;
if (manageState) {
(0, _trackContextState.trackContextState)(gl, {
copyState: false,
log: function log() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _log2.log.log.apply(_log2.log, [1].concat(args))();
}
});
}
if (isBrowser && debug) {
if (!globalThis.makeDebugContext) {
_log2.log.warn('WebGL debug mode not activated. import "@luma.gl/debug" to enable.')();
} else {
gl = globalThis.makeDebugContext(gl, options);
_log2.log.level = Math.max(_log2.log.level, 1);
}
}
gl._instrumented = true;
return gl;
}
function getContextDebugInfo(gl) {
var vendorMasked = gl.getParameter(7936);
var rendererMasked = gl.getParameter(7937);
var ext = gl.getExtension('WEBGL_debug_renderer_info');
var vendorUnmasked = ext && gl.getParameter(ext.UNMASKED_VENDOR_WEBGL || 7936);
var rendererUnmasked = ext && gl.getParameter(ext.UNMASKED_RENDERER_WEBGL || 7937);
return {
vendor: vendorUnmasked || vendorMasked,
renderer: rendererUnmasked || rendererMasked,
vendorMasked: vendorMasked,
rendererMasked: rendererMasked,
version: gl.getParameter(7938),
shadingLanguageVersion: gl.getParameter(35724)
};
}
function resizeGLContext(gl) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (gl.canvas) {
var devicePixelRatio = (0, _devicePixels.getDevicePixelRatio)(options.useDevicePixels);
setDevicePixelRatio(gl, devicePixelRatio, options);
return;
}
var ext = gl.getExtension('STACKGL_resize_drawingbuffer');
if (ext && "width" in options && "height" in options) {
ext.resize(options.width, options.height);
}
}
function createBrowserContext(canvas, options) {
var onError = options.onError;
var errorMessage = null;
var onCreateError = function onCreateError(error) {
return errorMessage = error.statusMessage || errorMessage;
};
canvas.addEventListener('webglcontextcreationerror', onCreateError, false);
var _options$webgl = options.webgl1,
webgl1 = _options$webgl === void 0 ? true : _options$webgl,
_options$webgl2 = options.webgl2,
webgl2 = _options$webgl2 === void 0 ? true : _options$webgl2;
var gl = null;
if (webgl2) {
gl = gl || canvas.getContext('webgl2', options);
gl = gl || canvas.getContext('experimental-webgl2', options);
}
if (webgl1) {
gl = gl || canvas.getContext('webgl', options);
gl = gl || canvas.getContext('experimental-webgl', options);
}
canvas.removeEventListener('webglcontextcreationerror', onCreateError, false);
if (!gl) {
return onError("Failed to create ".concat(webgl2 && !webgl1 ? 'WebGL2' : 'WebGL', " context: ").concat(errorMessage || 'Unknown error'));
}
if (options.onContextLost) {
canvas.addEventListener('webglcontextlost', options.onContextLost, false);
}
if (options.onContextRestored) {
canvas.addEventListener('webglcontextrestored', options.onContextRestored, false);
}
return gl;
}
function getCanvas(_ref) {
var canvas = _ref.canvas,
_ref$width = _ref.width,
width = _ref$width === void 0 ? 800 : _ref$width,
_ref$height = _ref.height,
height = _ref$height === void 0 ? 600 : _ref$height,
onError = _ref.onError;
var targetCanvas;
if (typeof canvas === 'string') {
var isPageLoaded = isPage && document.readyState === 'complete';
if (!isPageLoaded) {
onError("createGLContext called on canvas '".concat(canvas, "' before page was loaded"));
}
targetCanvas = document.getElementById(canvas);
} else if (canvas) {
targetCanvas = canvas;
} else {
targetCanvas = document.createElement('canvas');
targetCanvas.id = 'lumagl-canvas';
targetCanvas.style.width = Number.isFinite(width) ? "".concat(width, "px") : '100%';
targetCanvas.style.height = Number.isFinite(height) ? "".concat(height, "px") : '100%';
document.body.insertBefore(targetCanvas, document.body.firstChild);
}
return targetCanvas;
}
function logInfo(gl) {
var webGL = (0, _webglChecks.isWebGL2)(gl) ? 'WebGL2' : 'WebGL1';
var info = getContextDebugInfo(gl);
var driver = info ? "(".concat(info.vendor, ",").concat(info.renderer, ")") : '';
var debug = gl.debug ? ' debug' : '';
_log2.log.info(1, "".concat(webGL).concat(debug, " context ").concat(driver))();
}
function getVersion(gl) {
if (typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext) {
return 2;
}
return 1;
}
function setDevicePixelRatio(gl, devicePixelRatio, options) {
var clientWidth = 'width' in options ? options.width : gl.canvas.clientWidth;
var clientHeight = 'height' in options ? options.height : gl.canvas.clientHeight;
if (!clientWidth || !clientHeight) {
_log2.log.log(1, 'Canvas clientWidth/clientHeight is 0')();
devicePixelRatio = 1;
clientWidth = gl.canvas.width || 1;
clientHeight = gl.canvas.height || 1;
}
gl.luma = gl.luma || {};
gl.luma.canvasSizeInfo = gl.luma.canvasSizeInfo || {};
var cachedSize = gl.luma.canvasSizeInfo;
if (cachedSize.clientWidth !== clientWidth || cachedSize.clientHeight !== clientHeight || cachedSize.devicePixelRatio !== devicePixelRatio) {
var clampedPixelRatio = devicePixelRatio;
var canvasWidth = Math.floor(clientWidth * clampedPixelRatio);
var canvasHeight = Math.floor(clientHeight * clampedPixelRatio);
gl.canvas.width = canvasWidth;
gl.canvas.height = canvasHeight;
if (gl.drawingBufferWidth !== canvasWidth || gl.drawingBufferHeight !== canvasHeight) {
_log2.log.warn("Device pixel ratio clamped")();
clampedPixelRatio = Math.min(gl.drawingBufferWidth / clientWidth, gl.drawingBufferHeight / clientHeight);
gl.canvas.width = Math.floor(clientWidth * clampedPixelRatio);
gl.canvas.height = Math.floor(clientHeight * clampedPixelRatio);
}
Object.assign(gl.luma.canvasSizeInfo, {
clientWidth: clientWidth,
clientHeight: clientHeight,
devicePixelRatio: devicePixelRatio
});
}
}
//# sourceMappingURL=context.js.map