@deck.gl/core
Version:
deck.gl core library
1,425 lines (1,396 loc) • 1.45 MB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if (typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if (typeof define === 'function' && define.amd) define([], factory);
else if (typeof exports === 'object') exports['deck'] = factory();
else root['deck'] = factory();})(globalThis, function () {
"use strict";
var __exports__ = (() => {
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __export = (target2, all) => {
for (var name2 in all)
__defProp(target2, name2, { get: all[name2], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod3) => __copyProps(__defProp({}, "__esModule", { value: true }), mod3);
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
// bundle/index.ts
var bundle_exports = {};
__export(bundle_exports, {
AmbientLight: () => AmbientLight,
Attribute: () => Attribute,
AttributeManager: () => AttributeManager,
COORDINATE_SYSTEM: () => COORDINATE_SYSTEM,
CompositeLayer: () => CompositeLayer,
Controller: () => Controller,
Deck: () => Deck,
DeckGL: () => DeckGL,
DeckRenderer: () => DeckRenderer,
DirectionalLight: () => DirectionalLight,
FirstPersonController: () => FirstPersonController,
FirstPersonView: () => FirstPersonView,
FirstPersonViewport: () => FirstPersonViewport,
FlyToInterpolator: () => FlyToInterpolator,
Layer: () => Layer,
LayerExtension: () => LayerExtension,
LayerManager: () => LayerManager,
LightingEffect: () => LightingEffect,
LinearInterpolator: () => LinearInterpolator,
MapController: () => MapController,
MapView: () => MapView,
OPERATION: () => OPERATION,
OrbitController: () => OrbitController,
OrbitView: () => OrbitView,
OrbitViewport: () => OrbitViewport,
OrthographicController: () => OrthographicController,
OrthographicView: () => OrthographicView,
OrthographicViewport: () => OrthographicViewport,
PointLight: () => PointLight,
PostProcessEffect: () => PostProcessEffect,
TRANSITION_EVENTS: () => TRANSITION_EVENTS,
Tesselator: () => Tesselator,
TransitionInterpolator: () => TransitionInterpolator,
UNIT: () => UNIT,
VERSION: () => VERSION4,
View: () => View,
Viewport: () => Viewport,
WebMercatorViewport: () => WebMercatorViewport2,
_CameraLight: () => CameraLight,
_Component: () => Component,
_ComponentState: () => ComponentState,
_GlobeController: () => GlobeController,
_GlobeView: () => GlobeView,
_GlobeViewport: () => GlobeViewport,
_LayersPass: () => LayersPass,
_PickLayersPass: () => PickLayersPass,
_SunLight: () => SunLight,
_applyStyles: () => applyStyles,
_compareProps: () => compareProps,
_count: () => count,
_deepEqual: () => deepEqual2,
_fillArray: () => fillArray,
_flatten: () => flatten,
_memoize: () => memoize,
_mergeShaders: () => mergeShaders,
_registerLoggers: () => register,
_removeStyles: () => removeStyles,
assert: () => assert7,
createIterable: () => createIterable,
fp64LowPart: () => fp64LowPart2,
getShaderAssembler: () => getShaderAssembler,
gouraudLighting: () => gouraudLighting,
log: () => log_default,
phongLighting: () => phongLighting,
picking: () => picking_default,
project: () => project_default,
project32: () => project32_default,
shadow: () => shadow_default
});
// src/scripting/lumagl.ts
var lumagl_exports = {};
__export(lumagl_exports, {
Buffer: () => Buffer2,
BufferTransform: () => BufferTransform,
CubeGeometry: () => CubeGeometry,
Device: () => Device,
Framebuffer: () => Framebuffer,
Geometry: () => Geometry,
GroupNode: () => GroupNode,
Model: () => Model,
ModelNode: () => ModelNode,
ScenegraphNode: () => ScenegraphNode,
SphereGeometry: () => SphereGeometry,
Texture: () => Texture,
TextureTransform: () => TextureTransform,
attachDevice: () => attachDevice,
createDevice: () => createDevice,
enforceWebGL2: () => enforceWebGL2,
getBestAvailableAdapter: () => getBestAvailableAdapter,
getSupportedAdapters: () => getSupportedAdapters,
registerDevices: () => registerDevices,
setDefaultDeviceProps: () => setDefaultDeviceProps,
stats: () => stats
});
// ../../node_modules/@probe.gl/env/dist/lib/globals.js
var window_ = globalThis;
var document_ = globalThis.document || {};
var process_ = globalThis.process || {};
var console_ = globalThis.console;
var navigator_ = globalThis.navigator || {};
// ../../node_modules/@probe.gl/env/dist/lib/is-electron.js
function isElectron(mockUserAgent) {
if (typeof window !== "undefined" && window.process?.type === "renderer") {
return true;
}
if (typeof process !== "undefined" && Boolean(process.versions?.["electron"])) {
return true;
}
const realUserAgent = typeof navigator !== "undefined" && navigator.userAgent;
const userAgent2 = mockUserAgent || realUserAgent;
return Boolean(userAgent2 && userAgent2.indexOf("Electron") >= 0);
}
// ../../node_modules/@probe.gl/env/dist/lib/is-browser.js
function isBrowser() {
const isNode = (
// @ts-expect-error
typeof process === "object" && String(process) === "[object process]" && !process?.browser
);
return !isNode || isElectron();
}
// ../../node_modules/@probe.gl/env/dist/lib/get-browser.js
function getBrowser(mockUserAgent) {
if (!mockUserAgent && !isBrowser()) {
return "Node";
}
if (isElectron(mockUserAgent)) {
return "Electron";
}
const userAgent2 = mockUserAgent || navigator_.userAgent || "";
if (userAgent2.indexOf("Edge") > -1) {
return "Edge";
}
if (globalThis.chrome) {
return "Chrome";
}
if (globalThis.safari) {
return "Safari";
}
if (globalThis.mozInnerScreenX) {
return "Firefox";
}
return "Unknown";
}
// ../../node_modules/@probe.gl/env/dist/index.js
var VERSION = true ? "4.1.0" : "untranspiled source";
// ../../node_modules/@probe.gl/stats/dist/utils/hi-res-timestamp.js
function getHiResTimestamp() {
let timestamp;
if (typeof window !== "undefined" && window.performance) {
timestamp = window.performance.now();
} else if (typeof process !== "undefined" && process.hrtime) {
const timeParts = process.hrtime();
timestamp = timeParts[0] * 1e3 + timeParts[1] / 1e6;
} else {
timestamp = Date.now();
}
return timestamp;
}
// ../../node_modules/@probe.gl/stats/dist/lib/stat.js
var Stat = class {
constructor(name2, type) {
this.sampleSize = 1;
this.time = 0;
this.count = 0;
this.samples = 0;
this.lastTiming = 0;
this.lastSampleTime = 0;
this.lastSampleCount = 0;
this._count = 0;
this._time = 0;
this._samples = 0;
this._startTime = 0;
this._timerPending = false;
this.name = name2;
this.type = type;
this.reset();
}
reset() {
this.time = 0;
this.count = 0;
this.samples = 0;
this.lastTiming = 0;
this.lastSampleTime = 0;
this.lastSampleCount = 0;
this._count = 0;
this._time = 0;
this._samples = 0;
this._startTime = 0;
this._timerPending = false;
return this;
}
setSampleSize(samples) {
this.sampleSize = samples;
return this;
}
/** Call to increment count (+1) */
incrementCount() {
this.addCount(1);
return this;
}
/** Call to decrement count (-1) */
decrementCount() {
this.subtractCount(1);
return this;
}
/** Increase count */
addCount(value) {
this._count += value;
this._samples++;
this._checkSampling();
return this;
}
/** Decrease count */
subtractCount(value) {
this._count -= value;
this._samples++;
this._checkSampling();
return this;
}
/** Add an arbitrary timing and bump the count */
addTime(time) {
this._time += time;
this.lastTiming = time;
this._samples++;
this._checkSampling();
return this;
}
/** Start a timer */
timeStart() {
this._startTime = getHiResTimestamp();
this._timerPending = true;
return this;
}
/** End a timer. Adds to time and bumps the timing count. */
timeEnd() {
if (!this._timerPending) {
return this;
}
this.addTime(getHiResTimestamp() - this._startTime);
this._timerPending = false;
this._checkSampling();
return this;
}
getSampleAverageCount() {
return this.sampleSize > 0 ? this.lastSampleCount / this.sampleSize : 0;
}
/** Calculate average time / count for the previous window */
getSampleAverageTime() {
return this.sampleSize > 0 ? this.lastSampleTime / this.sampleSize : 0;
}
/** Calculate counts per second for the previous window */
getSampleHz() {
return this.lastSampleTime > 0 ? this.sampleSize / (this.lastSampleTime / 1e3) : 0;
}
getAverageCount() {
return this.samples > 0 ? this.count / this.samples : 0;
}
/** Calculate average time / count */
getAverageTime() {
return this.samples > 0 ? this.time / this.samples : 0;
}
/** Calculate counts per second */
getHz() {
return this.time > 0 ? this.samples / (this.time / 1e3) : 0;
}
_checkSampling() {
if (this._samples === this.sampleSize) {
this.lastSampleTime = this._time;
this.lastSampleCount = this._count;
this.count += this._count;
this.time += this._time;
this.samples += this._samples;
this._time = 0;
this._count = 0;
this._samples = 0;
}
}
};
// ../../node_modules/@probe.gl/stats/dist/lib/stats.js
var Stats = class {
constructor(options) {
this.stats = {};
this.id = options.id;
this.stats = {};
this._initializeStats(options.stats);
Object.seal(this);
}
/** Acquire a stat. Create if it doesn't exist. */
get(name2, type = "count") {
return this._getOrCreate({ name: name2, type });
}
get size() {
return Object.keys(this.stats).length;
}
/** Reset all stats */
reset() {
for (const stat of Object.values(this.stats)) {
stat.reset();
}
return this;
}
forEach(fn) {
for (const stat of Object.values(this.stats)) {
fn(stat);
}
}
getTable() {
const table = {};
this.forEach((stat) => {
table[stat.name] = {
time: stat.time || 0,
count: stat.count || 0,
average: stat.getAverageTime() || 0,
hz: stat.getHz() || 0
};
});
return table;
}
_initializeStats(stats2 = []) {
stats2.forEach((stat) => this._getOrCreate(stat));
}
_getOrCreate(stat) {
const { name: name2, type } = stat;
let result = this.stats[name2];
if (!result) {
if (stat instanceof Stat) {
result = stat;
} else {
result = new Stat(name2, type);
}
this.stats[name2] = result;
}
return result;
}
};
// ../../node_modules/@luma.gl/core/dist/utils/stats-manager.js
var StatsManager = class {
stats = /* @__PURE__ */ new Map();
getStats(name2) {
return this.get(name2);
}
get(name2) {
if (!this.stats.has(name2)) {
this.stats.set(name2, new Stats({ id: name2 }));
}
return this.stats.get(name2);
}
};
var lumaStats = new StatsManager();
// ../../node_modules/@probe.gl/log/dist/utils/local-storage.js
function getStorage(type) {
try {
const storage = window[type];
const x2 = "__storage_test__";
storage.setItem(x2, x2);
storage.removeItem(x2);
return storage;
} catch (e3) {
return null;
}
}
var LocalStorage = class {
constructor(id, defaultConfig, type = "sessionStorage") {
this.storage = getStorage(type);
this.id = id;
this.config = defaultConfig;
this._loadConfiguration();
}
getConfiguration() {
return this.config;
}
setConfiguration(configuration) {
Object.assign(this.config, configuration);
if (this.storage) {
const serialized = JSON.stringify(this.config);
this.storage.setItem(this.id, serialized);
}
}
// Get config from persistent store, if available
_loadConfiguration() {
let configuration = {};
if (this.storage) {
const serializedConfiguration = this.storage.getItem(this.id);
configuration = serializedConfiguration ? JSON.parse(serializedConfiguration) : {};
}
Object.assign(this.config, configuration);
return this;
}
};
// ../../node_modules/@probe.gl/log/dist/utils/formatters.js
function formatTime(ms) {
let formatted;
if (ms < 10) {
formatted = `${ms.toFixed(2)}ms`;
} else if (ms < 100) {
formatted = `${ms.toFixed(1)}ms`;
} else if (ms < 1e3) {
formatted = `${ms.toFixed(0)}ms`;
} else {
formatted = `${(ms / 1e3).toFixed(2)}s`;
}
return formatted;
}
function leftPad(string, length4 = 8) {
const padLength = Math.max(length4 - string.length, 0);
return `${" ".repeat(padLength)}${string}`;
}
// ../../node_modules/@probe.gl/log/dist/utils/color.js
var COLOR;
(function(COLOR2) {
COLOR2[COLOR2["BLACK"] = 30] = "BLACK";
COLOR2[COLOR2["RED"] = 31] = "RED";
COLOR2[COLOR2["GREEN"] = 32] = "GREEN";
COLOR2[COLOR2["YELLOW"] = 33] = "YELLOW";
COLOR2[COLOR2["BLUE"] = 34] = "BLUE";
COLOR2[COLOR2["MAGENTA"] = 35] = "MAGENTA";
COLOR2[COLOR2["CYAN"] = 36] = "CYAN";
COLOR2[COLOR2["WHITE"] = 37] = "WHITE";
COLOR2[COLOR2["BRIGHT_BLACK"] = 90] = "BRIGHT_BLACK";
COLOR2[COLOR2["BRIGHT_RED"] = 91] = "BRIGHT_RED";
COLOR2[COLOR2["BRIGHT_GREEN"] = 92] = "BRIGHT_GREEN";
COLOR2[COLOR2["BRIGHT_YELLOW"] = 93] = "BRIGHT_YELLOW";
COLOR2[COLOR2["BRIGHT_BLUE"] = 94] = "BRIGHT_BLUE";
COLOR2[COLOR2["BRIGHT_MAGENTA"] = 95] = "BRIGHT_MAGENTA";
COLOR2[COLOR2["BRIGHT_CYAN"] = 96] = "BRIGHT_CYAN";
COLOR2[COLOR2["BRIGHT_WHITE"] = 97] = "BRIGHT_WHITE";
})(COLOR || (COLOR = {}));
var BACKGROUND_INCREMENT = 10;
function getColor(color) {
if (typeof color !== "string") {
return color;
}
color = color.toUpperCase();
return COLOR[color] || COLOR.WHITE;
}
function addColor(string, color, background) {
if (!isBrowser && typeof string === "string") {
if (color) {
const colorCode = getColor(color);
string = `\x1B[${colorCode}m${string}\x1B[39m`;
}
if (background) {
const colorCode = getColor(background);
string = `\x1B[${colorCode + BACKGROUND_INCREMENT}m${string}\x1B[49m`;
}
}
return string;
}
// ../../node_modules/@probe.gl/log/dist/utils/autobind.js
function autobind(obj, predefined = ["constructor"]) {
const proto = Object.getPrototypeOf(obj);
const propNames = Object.getOwnPropertyNames(proto);
const object = obj;
for (const key of propNames) {
const value = object[key];
if (typeof value === "function") {
if (!predefined.find((name2) => key === name2)) {
object[key] = value.bind(obj);
}
}
}
}
// ../../node_modules/@probe.gl/log/dist/utils/assert.js
function assert(condition, message2) {
if (!condition) {
throw new Error(message2 || "Assertion failed");
}
}
// ../../node_modules/@probe.gl/log/dist/utils/hi-res-timestamp.js
function getHiResTimestamp2() {
let timestamp;
if (isBrowser() && window_.performance) {
timestamp = window_?.performance?.now?.();
} else if ("hrtime" in process_) {
const timeParts = process_?.hrtime?.();
timestamp = timeParts[0] * 1e3 + timeParts[1] / 1e6;
} else {
timestamp = Date.now();
}
return timestamp;
}
// ../../node_modules/@probe.gl/log/dist/log.js
var originalConsole = {
debug: isBrowser() ? console.debug || console.log : console.log,
log: console.log,
info: console.info,
warn: console.warn,
error: console.error
};
var DEFAULT_LOG_CONFIGURATION = {
enabled: true,
level: 0
};
function noop() {
}
var cache = {};
var ONCE = { once: true };
var Log = class {
constructor({ id } = { id: "" }) {
this.VERSION = VERSION;
this._startTs = getHiResTimestamp2();
this._deltaTs = getHiResTimestamp2();
this.userData = {};
this.LOG_THROTTLE_TIMEOUT = 0;
this.id = id;
this.userData = {};
this._storage = new LocalStorage(`__probe-${this.id}__`, DEFAULT_LOG_CONFIGURATION);
this.timeStamp(`${this.id} started`);
autobind(this);
Object.seal(this);
}
set level(newLevel) {
this.setLevel(newLevel);
}
get level() {
return this.getLevel();
}
isEnabled() {
return this._storage.config.enabled;
}
getLevel() {
return this._storage.config.level;
}
/** @return milliseconds, with fractions */
getTotal() {
return Number((getHiResTimestamp2() - this._startTs).toPrecision(10));
}
/** @return milliseconds, with fractions */
getDelta() {
return Number((getHiResTimestamp2() - this._deltaTs).toPrecision(10));
}
/** @deprecated use logLevel */
set priority(newPriority) {
this.level = newPriority;
}
/** @deprecated use logLevel */
get priority() {
return this.level;
}
/** @deprecated use logLevel */
getPriority() {
return this.level;
}
// Configure
enable(enabled = true) {
this._storage.setConfiguration({ enabled });
return this;
}
setLevel(level) {
this._storage.setConfiguration({ level });
return this;
}
/** return the current status of the setting */
get(setting) {
return this._storage.config[setting];
}
// update the status of the setting
set(setting, value) {
this._storage.setConfiguration({ [setting]: value });
}
/** Logs the current settings as a table */
settings() {
if (console.table) {
console.table(this._storage.config);
} else {
console.log(this._storage.config);
}
}
// Unconditional logging
assert(condition, message2) {
if (!condition) {
throw new Error(message2 || "Assertion failed");
}
}
warn(message2) {
return this._getLogFunction(0, message2, originalConsole.warn, arguments, ONCE);
}
error(message2) {
return this._getLogFunction(0, message2, originalConsole.error, arguments);
}
/** Print a deprecation warning */
deprecated(oldUsage, newUsage) {
return this.warn(`\`${oldUsage}\` is deprecated and will be removed in a later version. Use \`${newUsage}\` instead`);
}
/** Print a removal warning */
removed(oldUsage, newUsage) {
return this.error(`\`${oldUsage}\` has been removed. Use \`${newUsage}\` instead`);
}
probe(logLevel, message2) {
return this._getLogFunction(logLevel, message2, originalConsole.log, arguments, {
time: true,
once: true
});
}
log(logLevel, message2) {
return this._getLogFunction(logLevel, message2, originalConsole.debug, arguments);
}
info(logLevel, message2) {
return this._getLogFunction(logLevel, message2, console.info, arguments);
}
once(logLevel, message2) {
return this._getLogFunction(logLevel, message2, originalConsole.debug || originalConsole.info, arguments, ONCE);
}
/** Logs an object as a table */
table(logLevel, table, columns) {
if (table) {
return this._getLogFunction(logLevel, table, console.table || noop, columns && [columns], {
tag: getTableHeader(table)
});
}
return noop;
}
time(logLevel, message2) {
return this._getLogFunction(logLevel, message2, console.time ? console.time : console.info);
}
timeEnd(logLevel, message2) {
return this._getLogFunction(logLevel, message2, console.timeEnd ? console.timeEnd : console.info);
}
timeStamp(logLevel, message2) {
return this._getLogFunction(logLevel, message2, console.timeStamp || noop);
}
group(logLevel, message2, opts = { collapsed: false }) {
const options = normalizeArguments({ logLevel, message: message2, opts });
const { collapsed } = opts;
options.method = (collapsed ? console.groupCollapsed : console.group) || console.info;
return this._getLogFunction(options);
}
groupCollapsed(logLevel, message2, opts = {}) {
return this.group(logLevel, message2, Object.assign({}, opts, { collapsed: true }));
}
groupEnd(logLevel) {
return this._getLogFunction(logLevel, "", console.groupEnd || noop);
}
// EXPERIMENTAL
withGroup(logLevel, message2, func) {
this.group(logLevel, message2)();
try {
func();
} finally {
this.groupEnd(logLevel)();
}
}
trace() {
if (console.trace) {
console.trace();
}
}
// PRIVATE METHODS
/** Deduces log level from a variety of arguments */
_shouldLog(logLevel) {
return this.isEnabled() && this.getLevel() >= normalizeLogLevel(logLevel);
}
_getLogFunction(logLevel, message2, method, args, opts) {
if (this._shouldLog(logLevel)) {
opts = normalizeArguments({ logLevel, message: message2, args, opts });
method = method || opts.method;
assert(method);
opts.total = this.getTotal();
opts.delta = this.getDelta();
this._deltaTs = getHiResTimestamp2();
const tag = opts.tag || opts.message;
if (opts.once && tag) {
if (!cache[tag]) {
cache[tag] = getHiResTimestamp2();
} else {
return noop;
}
}
message2 = decorateMessage(this.id, opts.message, opts);
return method.bind(console, message2, ...opts.args);
}
return noop;
}
};
Log.VERSION = VERSION;
function normalizeLogLevel(logLevel) {
if (!logLevel) {
return 0;
}
let resolvedLevel;
switch (typeof logLevel) {
case "number":
resolvedLevel = logLevel;
break;
case "object":
resolvedLevel = logLevel.logLevel || logLevel.priority || 0;
break;
default:
return 0;
}
assert(Number.isFinite(resolvedLevel) && resolvedLevel >= 0);
return resolvedLevel;
}
function normalizeArguments(opts) {
const { logLevel, message: message2 } = opts;
opts.logLevel = normalizeLogLevel(logLevel);
const args = opts.args ? Array.from(opts.args) : [];
while (args.length && args.shift() !== message2) {
}
switch (typeof logLevel) {
case "string":
case "function":
if (message2 !== void 0) {
args.unshift(message2);
}
opts.message = logLevel;
break;
case "object":
Object.assign(opts, logLevel);
break;
default:
}
if (typeof opts.message === "function") {
opts.message = opts.message();
}
const messageType = typeof opts.message;
assert(messageType === "string" || messageType === "object");
return Object.assign(opts, { args }, opts.opts);
}
function decorateMessage(id, message2, opts) {
if (typeof message2 === "string") {
const time = opts.time ? leftPad(formatTime(opts.total)) : "";
message2 = opts.time ? `${id}: ${time} ${message2}` : `${id}: ${message2}`;
message2 = addColor(message2, opts.color, opts.background);
}
return message2;
}
function getTableHeader(table) {
for (const key in table) {
for (const title in table[key]) {
return title || "untitled";
}
}
return "empty";
}
// ../../node_modules/@probe.gl/log/dist/init.js
globalThis.probe = {};
// ../../node_modules/@probe.gl/log/dist/index.js
var dist_default = new Log({ id: "@probe.gl/log" });
// ../../node_modules/@luma.gl/core/dist/utils/log.js
var log = new Log({ id: "luma.gl" });
// ../../node_modules/@luma.gl/core/dist/utils/uid.js
var uidCounters = {};
function uid(id = "id") {
uidCounters[id] = uidCounters[id] || 1;
const count2 = uidCounters[id]++;
return `${id}-${count2}`;
}
// ../../node_modules/@luma.gl/core/dist/adapter/resources/resource.js
var Resource = class {
toString() {
return `${this[Symbol.toStringTag] || this.constructor.name}:"${this.id}"`;
}
/** props.id, for debugging. */
id;
props;
userData = {};
_device;
/** Whether this resource has been destroyed */
destroyed = false;
/** For resources that allocate GPU memory */
allocatedBytes = 0;
/** Attached resources will be destroyed when this resource is destroyed. Tracks auto-created "sub" resources. */
_attachedResources = /* @__PURE__ */ new Set();
/**
* Create a new Resource. Called from Subclass
*/
constructor(device, props, defaultProps3) {
if (!device) {
throw new Error("no device");
}
this._device = device;
this.props = selectivelyMerge(props, defaultProps3);
const id = this.props.id !== "undefined" ? this.props.id : uid(this[Symbol.toStringTag]);
this.props.id = id;
this.id = id;
this.userData = this.props.userData || {};
this.addStats();
}
/**
* destroy can be called on any resource to release it before it is garbage collected.
*/
destroy() {
this.destroyResource();
}
/** @deprecated Use destroy() */
delete() {
this.destroy();
return this;
}
/**
* Combines a map of user props and default props, only including props from defaultProps
* @returns returns a map of overridden default props
*/
getProps() {
return this.props;
}
// ATTACHED RESOURCES
/**
* Attaches a resource. Attached resources are auto destroyed when this resource is destroyed
* Called automatically when sub resources are auto created but can be called by application
*/
attachResource(resource) {
this._attachedResources.add(resource);
}
/**
* Detach an attached resource. The resource will no longer be auto-destroyed when this resource is destroyed.
*/
detachResource(resource) {
this._attachedResources.delete(resource);
}
/**
* Destroys a resource (only if owned), and removes from the owned (auto-destroy) list for this resource.
*/
destroyAttachedResource(resource) {
if (this._attachedResources.delete(resource)) {
resource.destroy();
}
}
/** Destroy all owned resources. Make sure the resources are no longer needed before calling. */
destroyAttachedResources() {
for (const resource of Object.values(this._attachedResources)) {
resource.destroy();
}
this._attachedResources = /* @__PURE__ */ new Set();
}
// PROTECTED METHODS
/** Perform all destroy steps. Can be called by derived resources when overriding destroy() */
destroyResource() {
this.destroyAttachedResources();
this.removeStats();
this.destroyed = true;
}
/** Called by .destroy() to track object destruction. Subclass must call if overriding destroy() */
removeStats() {
const stats2 = this._device.statsManager.getStats("Resource Counts");
const name2 = this[Symbol.toStringTag];
stats2.get(`${name2}s Active`).decrementCount();
}
/** Called by subclass to track memory allocations */
trackAllocatedMemory(bytes, name2 = this[Symbol.toStringTag]) {
const stats2 = this._device.statsManager.getStats("Resource Counts");
stats2.get("GPU Memory").addCount(bytes);
stats2.get(`${name2} Memory`).addCount(bytes);
this.allocatedBytes = bytes;
}
/** Called by subclass to track memory deallocations */
trackDeallocatedMemory(name2 = this[Symbol.toStringTag]) {
const stats2 = this._device.statsManager.getStats("Resource Counts");
stats2.get("GPU Memory").subtractCount(this.allocatedBytes);
stats2.get(`${name2} Memory`).subtractCount(this.allocatedBytes);
this.allocatedBytes = 0;
}
/** Called by resource constructor to track object creation */
addStats() {
const stats2 = this._device.statsManager.getStats("Resource Counts");
const name2 = this[Symbol.toStringTag];
stats2.get("Resources Created").incrementCount();
stats2.get(`${name2}s Created`).incrementCount();
stats2.get(`${name2}s Active`).incrementCount();
}
};
/** Default properties for resource */
__publicField(Resource, "defaultProps", {
id: "undefined",
handle: void 0,
userData: void 0
});
function selectivelyMerge(props, defaultProps3) {
const mergedProps = { ...defaultProps3 };
for (const key in props) {
if (props[key] !== void 0) {
mergedProps[key] = props[key];
}
}
return mergedProps;
}
// ../../node_modules/@luma.gl/core/dist/adapter/resources/buffer.js
var _Buffer = class extends Resource {
get [Symbol.toStringTag]() {
return "Buffer";
}
/** The usage with which this buffer was created */
usage;
/** For index buffers, whether indices are 16 or 32 bit */
indexType;
/** "Time" of last update, can be used to check if redraw is needed */
updateTimestamp;
constructor(device, props) {
const deducedProps = { ...props };
if ((props.usage || 0) & _Buffer.INDEX && !props.indexType) {
if (props.data instanceof Uint32Array) {
deducedProps.indexType = "uint32";
} else if (props.data instanceof Uint16Array) {
deducedProps.indexType = "uint16";
}
}
delete deducedProps.data;
super(device, deducedProps, _Buffer.defaultProps);
this.usage = deducedProps.usage || 0;
this.indexType = deducedProps.indexType;
this.updateTimestamp = device.incrementTimestamp();
}
/**
* Create a copy of this Buffer with new byteLength, with same props but of the specified size.
* @note Does not copy contents of the cloned Buffer.
*/
clone(props) {
return this.device.createBuffer({ ...this.props, ...props });
}
/** Read data synchronously. @note WebGL2 only */
readSyncWebGL(byteOffset, byteLength) {
throw new Error("not implemented");
}
/** A partial CPU-side copy of the data in this buffer, for debugging purposes */
debugData = new ArrayBuffer(0);
/** This doesn't handle partial non-zero offset updates correctly */
_setDebugData(data, byteOffset, byteLength) {
const arrayBuffer2 = ArrayBuffer.isView(data) ? data.buffer : data;
const debugDataLength = Math.min(data ? data.byteLength : byteLength, _Buffer.DEBUG_DATA_MAX_LENGTH);
if (arrayBuffer2 === null) {
this.debugData = new ArrayBuffer(debugDataLength);
} else if (byteOffset === 0 && byteLength === arrayBuffer2.byteLength) {
this.debugData = arrayBuffer2.slice(0, debugDataLength);
} else {
this.debugData = arrayBuffer2.slice(byteOffset, byteOffset + debugDataLength);
}
}
};
var Buffer2 = _Buffer;
__publicField(Buffer2, "defaultProps", {
...Resource.defaultProps,
usage: 0,
// Buffer.COPY_DST | Buffer.COPY_SRC
byteLength: 0,
byteOffset: 0,
data: null,
indexType: "uint16",
mappedAtCreation: false
});
// Usage Flags
__publicField(Buffer2, "MAP_READ", 1);
__publicField(Buffer2, "MAP_WRITE", 2);
__publicField(Buffer2, "COPY_SRC", 4);
__publicField(Buffer2, "COPY_DST", 8);
/** Index buffer */
__publicField(Buffer2, "INDEX", 16);
/** Vertex buffer */
__publicField(Buffer2, "VERTEX", 32);
/** Uniform buffer */
__publicField(Buffer2, "UNIFORM", 64);
/** Storage buffer */
__publicField(Buffer2, "STORAGE", 128);
__publicField(Buffer2, "INDIRECT", 256);
__publicField(Buffer2, "QUERY_RESOLVE", 512);
// PROTECTED METHODS (INTENDED FOR USE BY OTHER FRAMEWORK CODE ONLY)
/** Max amount of debug data saved. Two vec4's */
__publicField(Buffer2, "DEBUG_DATA_MAX_LENGTH", 32);
// ../../node_modules/@luma.gl/core/dist/gpu-type-utils/decode-data-type.js
function decodeVertexType(type) {
const dataType = TYPE_MAP[type];
const bytes = getDataTypeBytes(dataType);
const normalized = type.includes("norm");
const integer = !normalized && !type.startsWith("float");
const signed = type.startsWith("s");
return {
dataType: TYPE_MAP[type],
byteLength: bytes,
integer,
signed,
normalized
};
}
function getDataTypeBytes(type) {
const bytes = TYPE_SIZES[type];
return bytes;
}
var TYPE_MAP = {
uint8: "uint8",
sint8: "sint8",
unorm8: "uint8",
snorm8: "sint8",
uint16: "uint16",
sint16: "sint16",
unorm16: "uint16",
snorm16: "sint16",
float16: "float16",
float32: "float32",
uint32: "uint32",
sint32: "sint32"
};
var TYPE_SIZES = {
uint8: 1,
sint8: 1,
uint16: 2,
sint16: 2,
float16: 2,
float32: 4,
uint32: 4,
sint32: 4
};
// ../../node_modules/@luma.gl/core/dist/gpu-type-utils/texture-format-table.js
var texture_compression_bc = "texture-compression-bc";
var texture_compression_astc = "texture-compression-astc";
var texture_compression_etc2 = "texture-compression-etc2";
var texture_compression_etc1_webgl = "texture-compression-etc1-webgl";
var texture_compression_pvrtc_webgl = "texture-compression-pvrtc-webgl";
var texture_compression_atc_webgl = "texture-compression-atc-webgl";
var float32_renderable = "float32-renderable-webgl";
var float16_renderable = "float16-renderable-webgl";
var rgb9e5ufloat_renderable = "rgb9e5ufloat-renderable-webgl";
var snorm8_renderable = "snorm8-renderable-webgl";
var norm16_renderable = "norm16-renderable-webgl";
var snorm16_renderable = "snorm16-renderable-webgl";
var float32_filterable = "float32-filterable";
var float16_filterable = "float16-filterable-webgl";
function getTextureFormatDefinition(format) {
const info = TEXTURE_FORMAT_TABLE[format];
if (!info) {
throw new Error(`Unsupported texture format ${format}`);
}
return info;
}
var TEXTURE_FORMAT_TABLE = {
// 8-bit formats
"r8unorm": {},
"r8snorm": { render: snorm8_renderable },
"r8uint": {},
"r8sint": {},
// 16-bit formats
"rg8unorm": {},
"rg8snorm": { render: snorm8_renderable },
"rg8uint": {},
"rg8sint": {},
"r16uint": {},
"r16sint": {},
"r16float": { render: float16_renderable, filter: "float16-filterable-webgl" },
"r16unorm-webgl": { f: norm16_renderable },
"r16snorm-webgl": { f: snorm16_renderable },
// Packed 16-bit formats
"rgba4unorm-webgl": { channels: "rgba", bitsPerChannel: [4, 4, 4, 4], packed: true },
"rgb565unorm-webgl": { channels: "rgb", bitsPerChannel: [5, 6, 5, 0], packed: true },
"rgb5a1unorm-webgl": { channels: "rgba", bitsPerChannel: [5, 5, 5, 1], packed: true },
// 24-bit formats
"rgb8unorm-webgl": {},
"rgb8snorm-webgl": {},
// 32-bit formats
"rgba8unorm": {},
"rgba8unorm-srgb": {},
"rgba8snorm": { render: snorm8_renderable },
"rgba8uint": {},
"rgba8sint": {},
// 32-bit, reverse colors, webgpu only
"bgra8unorm": {},
"bgra8unorm-srgb": {},
"rg16uint": {},
"rg16sint": {},
"rg16float": { render: float16_renderable, filter: float16_filterable },
"rg16unorm-webgl": { render: norm16_renderable },
"rg16snorm-webgl": { render: snorm16_renderable },
"r32uint": {},
"r32sint": {},
"r32float": { render: float32_renderable, filter: float32_filterable },
// Packed 32 bit formats
"rgb9e5ufloat": { channels: "rgb", packed: true, render: rgb9e5ufloat_renderable },
// , filter: true},
"rg11b10ufloat": { channels: "rgb", bitsPerChannel: [11, 11, 10, 0], packed: true, p: 1, render: float32_renderable },
"rgb10a2unorm": { channels: "rgba", bitsPerChannel: [10, 10, 10, 2], packed: true, p: 1 },
"rgb10a2uint-webgl": { channels: "rgba", bitsPerChannel: [10, 10, 10, 2], packed: true, p: 1, wgpu: false },
// 48-bit formats
"rgb16unorm-webgl": { f: norm16_renderable },
// rgb not renderable
"rgb16snorm-webgl": { f: norm16_renderable },
// rgb not renderable
// 64-bit formats
"rg32uint": {},
"rg32sint": {},
"rg32float": { render: false, filter: float32_filterable },
"rgba16uint": {},
"rgba16sint": {},
"rgba16float": { render: float16_renderable, filter: float16_filterable },
"rgba16unorm-webgl": { render: norm16_renderable },
"rgba16snorm-webgl": { render: snorm16_renderable },
// 96-bit formats (deprecated!)
"rgb32float-webgl": { render: float32_renderable, filter: float32_filterable },
// 128-bit formats
"rgba32uint": {},
"rgba32sint": {},
"rgba32float": { render: float32_renderable, filter: float32_filterable },
// Depth/stencil
// Depth and stencil formats
stencil8: { attachment: "stencil", bitsPerChannel: [8, 0, 0, 0], dataType: "uint8" },
"depth16unorm": { attachment: "depth", bitsPerChannel: [16, 0, 0, 0], dataType: "uint16" },
"depth24plus": { attachment: "depth", bitsPerChannel: [24, 0, 0, 0], dataType: "uint32" },
"depth32float": { attachment: "depth", bitsPerChannel: [32, 0, 0, 0], dataType: "float32" },
// The depth component of the "depth24plus" and "depth24plus-stencil8" formats may be implemented as either a 24-bit depth value or a "depth32float" value.
"depth24plus-stencil8": { attachment: "depth-stencil", bitsPerChannel: [24, 8, 0, 0], packed: true },
// "depth32float-stencil8" feature
"depth32float-stencil8": { attachment: "depth-stencil", bitsPerChannel: [32, 8, 0, 0], packed: true },
// BC compressed formats: check device.features.has("texture-compression-bc");
"bc1-rgb-unorm-webgl": { f: texture_compression_bc },
"bc1-rgb-unorm-srgb-webgl": { f: texture_compression_bc },
"bc1-rgba-unorm": { f: texture_compression_bc },
"bc1-rgba-unorm-srgb": { f: texture_compression_bc },
"bc2-rgba-unorm": { f: texture_compression_bc },
"bc2-rgba-unorm-srgb": { f: texture_compression_bc },
"bc3-rgba-unorm": { f: texture_compression_bc },
"bc3-rgba-unorm-srgb": { f: texture_compression_bc },
"bc4-r-unorm": { f: texture_compression_bc },
"bc4-r-snorm": { f: texture_compression_bc },
"bc5-rg-unorm": { f: texture_compression_bc },
"bc5-rg-snorm": { f: texture_compression_bc },
"bc6h-rgb-ufloat": { f: texture_compression_bc },
"bc6h-rgb-float": { f: texture_compression_bc },
"bc7-rgba-unorm": { f: texture_compression_bc },
"bc7-rgba-unorm-srgb": { f: texture_compression_bc },
// WEBGL_compressed_texture_etc: device.features.has("texture-compression-etc2")
// Note: Supposedly guaranteed availability compressed formats in WebGL2, but through CPU decompression
"etc2-rgb8unorm": { f: texture_compression_etc2 },
"etc2-rgb8unorm-srgb": { f: texture_compression_etc2 },
"etc2-rgb8a1unorm": { f: texture_compression_etc2 },
"etc2-rgb8a1unorm-srgb": { f: texture_compression_etc2 },
"etc2-rgba8unorm": { f: texture_compression_etc2 },
"etc2-rgba8unorm-srgb": { f: texture_compression_etc2 },
"eac-r11unorm": { f: texture_compression_etc2 },
"eac-r11snorm": { f: texture_compression_etc2 },
"eac-rg11unorm": { f: texture_compression_etc2 },
"eac-rg11snorm": { f: texture_compression_etc2 },
// X_ASTC compressed formats: device.features.has("texture-compression-astc")
"astc-4x4-unorm": { f: texture_compression_astc },
"astc-4x4-unorm-srgb": { f: texture_compression_astc },
"astc-5x4-unorm": { f: texture_compression_astc },
"astc-5x4-unorm-srgb": { f: texture_compression_astc },
"astc-5x5-unorm": { f: texture_compression_astc },
"astc-5x5-unorm-srgb": { f: texture_compression_astc },
"astc-6x5-unorm": { f: texture_compression_astc },
"astc-6x5-unorm-srgb": { f: texture_compression_astc },
"astc-6x6-unorm": { f: texture_compression_astc },
"astc-6x6-unorm-srgb": { f: texture_compression_astc },
"astc-8x5-unorm": { f: texture_compression_astc },
"astc-8x5-unorm-srgb": { f: texture_compression_astc },
"astc-8x6-unorm": { f: texture_compression_astc },
"astc-8x6-unorm-srgb": { f: texture_compression_astc },
"astc-8x8-unorm": { f: texture_compression_astc },
"astc-8x8-unorm-srgb": { f: texture_compression_astc },
"astc-10x5-unorm": { f: texture_compression_astc },
"astc-10x5-unorm-srgb": { f: texture_compression_astc },
"astc-10x6-unorm": { f: texture_compression_astc },
"astc-10x6-unorm-srgb": { f: texture_compression_astc },
"astc-10x8-unorm": { f: texture_compression_astc },
"astc-10x8-unorm-srgb": { f: texture_compression_astc },
"astc-10x10-unorm": { f: texture_compression_astc },
"astc-10x10-unorm-srgb": { f: texture_compression_astc },
"astc-12x10-unorm": { f: texture_compression_astc },
"astc-12x10-unorm-srgb": { f: texture_compression_astc },
"astc-12x12-unorm": { f: texture_compression_astc },
"astc-12x12-unorm-srgb": { f: texture_compression_astc },
// WEBGL_compressed_texture_pvrtc
"pvrtc-rgb4unorm-webgl": { f: texture_compression_pvrtc_webgl },
"pvrtc-rgba4unorm-webgl": { f: texture_compression_pvrtc_webgl },
"pvrtc-rbg2unorm-webgl": { f: texture_compression_pvrtc_webgl },
"pvrtc-rgba2unorm-webgl": { f: texture_compression_pvrtc_webgl },
// WEBGL_compressed_texture_etc1
"etc1-rbg-unorm-webgl": { f: texture_compression_etc1_webgl },
// WEBGL_compressed_texture_atc
"atc-rgb-unorm-webgl": { f: texture_compression_atc_webgl },
"atc-rgba-unorm-webgl": { f: texture_compression_atc_webgl },
"atc-rgbai-unorm-webgl": { f: texture_compression_atc_webgl }
};
// ../../node_modules/@luma.gl/core/dist/gpu-type-utils/decode-texture-format.js
var COMPRESSED_TEXTURE_FORMAT_PREFIXES = [
"bc1",
"bc2",
"bc3",
"bc4",
"bc5",
"bc6",
"bc7",
"etc1",
"etc2",
"eac",
"atc",
"astc",
"pvrtc"
];
var RGB_FORMAT_REGEX = /^(r|rg|rgb|rgba|bgra)([0-9]*)([a-z]*)(-srgb)?(-webgl)?$/;
function isTextureFormatCompressed(format) {
return COMPRESSED_TEXTURE_FORMAT_PREFIXES.some((prefix) => format.startsWith(prefix));
}
function decodeTextureFormat(format) {
let formatInfo = decodeTextureFormatUsingTable(format);
if (isTextureFormatCompressed(format)) {
formatInfo.channels = "rgb";
formatInfo.components = 3;
formatInfo.bytesPerPixel = 1;
formatInfo.srgb = false;
formatInfo.compressed = true;
const blockSize = getCompressedTextureBlockSize(format);
if (blockSize) {
formatInfo.blockWidth = blockSize.blockWidth;
formatInfo.blockHeight = blockSize.blockHeight;
}
}
const matches3 = RGB_FORMAT_REGEX.exec(format);
if (matches3) {
const [, channels, length4, type, srgb, suffix] = matches3;
const dataType = `${type}${length4}`;
const decodedType = decodeVertexType(dataType);
const bits = decodedType.byteLength * 8;
const components = channels.length;
const bitsPerChannel = [
bits,
components >= 2 ? bits : 0,
components >= 3 ? bits : 0,
components >= 4 ? bits : 0
];
formatInfo = {
format,
attachment: formatInfo.attachment,
dataType: decodedType.dataType,
components,
channels,
integer: decodedType.integer,
signed: decodedType.signed,
normalized: decodedType.normalized,
bitsPerChannel,
bytesPerPixel: decodedType.byteLength * channels.length,
packed: formatInfo.packed,
srgb: formatInfo.srgb
};
if (suffix === "-webgl") {
formatInfo.webgl = true;
}
if (srgb === "-srgb") {
formatInfo.srgb = true;
}
}
if (format.endsWith("-webgl")) {
formatInfo.webgl = true;
}
if (format.endsWith("-srgb")) {
formatInfo.srgb = true;
}
return formatInfo;
}
function decodeTextureFormatUsingTable(format) {
const info = getTextureFormatDefinition(format);
const bytesPerPixel = info.bytesPerPixel || 1;
const bitsPerChannel = info.bitsPerChannel || [8, 8, 8, 8];
delete info.bitsPerChannel;
delete info.bytesPerPixel;
delete info.f;
delete info.render;
delete info.filter;
delete info.blend;
delete info.store;
const formatInfo = {
...info,
format,
attachment: info.attachment || "color",
channels: info.channels || "r",
components: info.components || info.channels?.length || 1,
bytesPerPixel,
bitsPerChannel,
dataType: info.dataType || "uint8",
srgb: info.srgb ?? false,
packed: info.packed ?? false,
webgl: info.webgl ?? false,
integer: info.integer ?? false,
signed: info.signed ?? false,
normalized: info.normalized ?? false,
compressed: info.compressed ?? false
};
return formatInfo;
}
function getCompressedTextureBlockSize(format) {
const REGEX = /.*-(\d+)x(\d+)-.*/;
const matches3 = REGEX.exec(format);
if (matches3) {
const [, blockWidth, blockHeight] = matches3;
return { blockWidth: Number(blockWidth), blockHeight: Number(blockHeight) };
}
return null;
}
// ../../node_modules/@luma.gl/core/dist/gpu-type-utils/texture-format-capabilities.js
function getTextureFormatCapabilities(format) {
const info = getTextureFormatDefinition(format);
const formatCapabilities = {
format,
create: info.f ?? true,
render: info.render ?? true,
filter: info.filter ?? true,
blend: info.blend ?? true,
store: info.store ?? true
};
const formatInfo = decodeTextureFormat(format);
const isDepthStencil = format.startsWith("depth") || format.startsWith("stencil");
const isSigned = formatInfo?.signed;
const isInteger = formatInfo?.integer;
const isWebGLSpecific = formatInfo?.webgl;
formatCapabilities.render &&= !isSigned;
formatCapabilities.filter &&= !isDepthStencil && !isSigned && !isInteger && !isWebGLSpecific;
return formatCapabilities;
}
// ../../node_modules/@luma.gl/core/dist/adapter/device.js
var DeviceLimits = class {
};
var DeviceFeatures = class {
features;
disabledFeatures;
constructor(features = [], disabledFeatures) {
this.features = new Set(features);
this.disabledFeatures = disabledFeatures || {};
}
*[Symbol.iterator]() {
yield* this.features;
}
has(feature) {
return !this.disabledFeatures?.[feature] && this.features.has(feature);
}
};
var _Device = class {
get [Symbol.toStringTag]() {
return "Device";
}
constructor(props) {
this.props = { ..._Device.defaultProps, ...props };
this.id = this.props.id || uid(this[Symbol.toStringTag].toLowerCase());
}
/** id of this device, primarily for debugging */
id;
/** A copy of the device props */
props;
/** Available for the application to store data on the device */
userData = {};
/** stats */
statsManager = lumaStats;
/** An abstract timestamp used for change tracking */
timestamp = 0;
/** True if this device has been reused during device creation (app has multiple references) */
_reused = false;
/** Used by other luma.gl modules to store data on the device */
_lumaData = {};
/** Determines what operations are supported on a texture format, checking against supported device features */
getTextureFormatCapabilities(format) {
const genericCapabilities = getTextureFormatCapabilities(format);
const checkFeature = (featureOrBoolean) => (typeof featureOrBoolean === "string" ? this.features.has(featureOrBoolean) : featureOrBoolean) ?? true;
const supported = checkFeature(genericCapabilities.create);
const deviceCapabilities = {
format,
create: supported,
render: supported && checkFeature(genericCapabilities.render),
filter: supported && checkFeature(genericCapabilities.filter),
blend: supported && checkFeature(genericCapabilities.blend),
store: supported && checkFeature(genericCapabilities.store)
};
return this._getDeviceSpecificTextureFormatCapabilities(deviceCapabilities);
}
/** Check if device supports a specific texture format (creation and `nearest` sampling) */
isTextureFormatSupported(format, capabilities) {
return this.getTextureFormatCapabilities(format).create;
}
/** Check if linear filtering (sampler interpolati