@luma.gl/effects 9.2.6 → 9.3.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +695 -279
- package/dist/dist.min.js +10 -9
- package/package.json +4 -5
package/dist/dist.dev.js
CHANGED
|
@@ -64,6 +64,7 @@ var __exports__ = (() => {
|
|
|
64
64
|
DeviceFeatures: () => DeviceFeatures,
|
|
65
65
|
DeviceLimits: () => DeviceLimits,
|
|
66
66
|
ExternalTexture: () => ExternalTexture,
|
|
67
|
+
Fence: () => Fence,
|
|
67
68
|
Framebuffer: () => Framebuffer,
|
|
68
69
|
PipelineLayout: () => PipelineLayout,
|
|
69
70
|
QuerySet: () => QuerySet,
|
|
@@ -82,20 +83,26 @@ var __exports__ = (() => {
|
|
|
82
83
|
VertexArray: () => VertexArray,
|
|
83
84
|
_getTextureFormatDefinition: () => getTextureFormatDefinition,
|
|
84
85
|
_getTextureFormatTable: () => getTextureFormatTable,
|
|
86
|
+
assert: () => assert2,
|
|
87
|
+
assertDefined: () => assertDefined,
|
|
85
88
|
getAttributeInfosFromLayouts: () => getAttributeInfosFromLayouts,
|
|
86
89
|
getAttributeShaderTypeInfo: () => getAttributeShaderTypeInfo,
|
|
87
90
|
getDataType: () => getDataType,
|
|
88
91
|
getDataTypeInfo: () => getDataTypeInfo,
|
|
92
|
+
getExternalImageSize: () => getExternalImageSize,
|
|
89
93
|
getNormalizedDataType: () => getNormalizedDataType,
|
|
90
94
|
getScratchArray: () => getScratchArray,
|
|
95
|
+
getTextureImageView: () => getTextureImageView,
|
|
91
96
|
getTypedArrayConstructor: () => getTypedArrayConstructor,
|
|
92
97
|
getVariableShaderTypeInfo: () => getVariableShaderTypeInfo,
|
|
93
98
|
getVertexFormatFromAttribute: () => getVertexFormatFromAttribute,
|
|
94
99
|
getVertexFormatInfo: () => getVertexFormatInfo,
|
|
100
|
+
isExternalImage: () => isExternalImage,
|
|
95
101
|
log: () => log,
|
|
96
102
|
luma: () => luma,
|
|
97
103
|
makeVertexFormat: () => makeVertexFormat,
|
|
98
104
|
readPixel: () => readPixel,
|
|
105
|
+
setTextureImageData: () => setTextureImageData,
|
|
99
106
|
textureFormatDecoder: () => textureFormatDecoder,
|
|
100
107
|
writePixel: () => writePixel
|
|
101
108
|
});
|
|
@@ -338,7 +345,139 @@ var __exports__ = (() => {
|
|
|
338
345
|
}
|
|
339
346
|
|
|
340
347
|
// ../../node_modules/@probe.gl/env/dist/index.js
|
|
341
|
-
var VERSION = true ? "4.1.
|
|
348
|
+
var VERSION = true ? "4.1.1" : "untranspiled source";
|
|
349
|
+
|
|
350
|
+
// ../../node_modules/@probe.gl/log/dist/utils/assert.js
|
|
351
|
+
function assert(condition, message) {
|
|
352
|
+
if (!condition) {
|
|
353
|
+
throw new Error(message || "Assertion failed");
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// ../../node_modules/@probe.gl/log/dist/loggers/log-utils.js
|
|
358
|
+
function normalizeLogLevel(logLevel) {
|
|
359
|
+
if (!logLevel) {
|
|
360
|
+
return 0;
|
|
361
|
+
}
|
|
362
|
+
let resolvedLevel;
|
|
363
|
+
switch (typeof logLevel) {
|
|
364
|
+
case "number":
|
|
365
|
+
resolvedLevel = logLevel;
|
|
366
|
+
break;
|
|
367
|
+
case "object":
|
|
368
|
+
resolvedLevel = logLevel.logLevel || logLevel.priority || 0;
|
|
369
|
+
break;
|
|
370
|
+
default:
|
|
371
|
+
return 0;
|
|
372
|
+
}
|
|
373
|
+
assert(Number.isFinite(resolvedLevel) && resolvedLevel >= 0);
|
|
374
|
+
return resolvedLevel;
|
|
375
|
+
}
|
|
376
|
+
function normalizeArguments(opts) {
|
|
377
|
+
const { logLevel, message } = opts;
|
|
378
|
+
opts.logLevel = normalizeLogLevel(logLevel);
|
|
379
|
+
const args = opts.args ? Array.from(opts.args) : [];
|
|
380
|
+
while (args.length && args.shift() !== message) {
|
|
381
|
+
}
|
|
382
|
+
switch (typeof logLevel) {
|
|
383
|
+
case "string":
|
|
384
|
+
case "function":
|
|
385
|
+
if (message !== void 0) {
|
|
386
|
+
args.unshift(message);
|
|
387
|
+
}
|
|
388
|
+
opts.message = logLevel;
|
|
389
|
+
break;
|
|
390
|
+
case "object":
|
|
391
|
+
Object.assign(opts, logLevel);
|
|
392
|
+
break;
|
|
393
|
+
default:
|
|
394
|
+
}
|
|
395
|
+
if (typeof opts.message === "function") {
|
|
396
|
+
opts.message = opts.message();
|
|
397
|
+
}
|
|
398
|
+
const messageType = typeof opts.message;
|
|
399
|
+
assert(messageType === "string" || messageType === "object");
|
|
400
|
+
return Object.assign(opts, { args }, opts.opts);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// ../../node_modules/@probe.gl/log/dist/loggers/base-log.js
|
|
404
|
+
var noop = () => {
|
|
405
|
+
};
|
|
406
|
+
var BaseLog = class {
|
|
407
|
+
constructor({ level = 0 } = {}) {
|
|
408
|
+
this.userData = {};
|
|
409
|
+
this._onceCache = /* @__PURE__ */ new Set();
|
|
410
|
+
this._level = level;
|
|
411
|
+
}
|
|
412
|
+
set level(newLevel) {
|
|
413
|
+
this.setLevel(newLevel);
|
|
414
|
+
}
|
|
415
|
+
get level() {
|
|
416
|
+
return this.getLevel();
|
|
417
|
+
}
|
|
418
|
+
setLevel(level) {
|
|
419
|
+
this._level = level;
|
|
420
|
+
return this;
|
|
421
|
+
}
|
|
422
|
+
getLevel() {
|
|
423
|
+
return this._level;
|
|
424
|
+
}
|
|
425
|
+
// Unconditional logging
|
|
426
|
+
warn(message, ...args) {
|
|
427
|
+
return this._log("warn", 0, message, args, { once: true });
|
|
428
|
+
}
|
|
429
|
+
error(message, ...args) {
|
|
430
|
+
return this._log("error", 0, message, args);
|
|
431
|
+
}
|
|
432
|
+
// Conditional logging
|
|
433
|
+
log(logLevel, message, ...args) {
|
|
434
|
+
return this._log("log", logLevel, message, args);
|
|
435
|
+
}
|
|
436
|
+
info(logLevel, message, ...args) {
|
|
437
|
+
return this._log("info", logLevel, message, args);
|
|
438
|
+
}
|
|
439
|
+
once(logLevel, message, ...args) {
|
|
440
|
+
return this._log("once", logLevel, message, args, { once: true });
|
|
441
|
+
}
|
|
442
|
+
_log(type, logLevel, message, args, options = {}) {
|
|
443
|
+
const normalized = normalizeArguments({
|
|
444
|
+
logLevel,
|
|
445
|
+
message,
|
|
446
|
+
args: this._buildArgs(logLevel, message, args),
|
|
447
|
+
opts: options
|
|
448
|
+
});
|
|
449
|
+
return this._createLogFunction(type, normalized, options);
|
|
450
|
+
}
|
|
451
|
+
_buildArgs(logLevel, message, args) {
|
|
452
|
+
return [logLevel, message, ...args];
|
|
453
|
+
}
|
|
454
|
+
_createLogFunction(type, normalized, options) {
|
|
455
|
+
if (!this._shouldLog(normalized.logLevel)) {
|
|
456
|
+
return noop;
|
|
457
|
+
}
|
|
458
|
+
const tag = this._getOnceTag(options.tag ?? normalized.tag ?? normalized.message);
|
|
459
|
+
if ((options.once || normalized.once) && tag !== void 0) {
|
|
460
|
+
if (this._onceCache.has(tag)) {
|
|
461
|
+
return noop;
|
|
462
|
+
}
|
|
463
|
+
this._onceCache.add(tag);
|
|
464
|
+
}
|
|
465
|
+
return this._emit(type, normalized);
|
|
466
|
+
}
|
|
467
|
+
_shouldLog(logLevel) {
|
|
468
|
+
return this.getLevel() >= normalizeLogLevel(logLevel);
|
|
469
|
+
}
|
|
470
|
+
_getOnceTag(tag) {
|
|
471
|
+
if (tag === void 0) {
|
|
472
|
+
return void 0;
|
|
473
|
+
}
|
|
474
|
+
try {
|
|
475
|
+
return typeof tag === "string" ? tag : String(tag);
|
|
476
|
+
} catch {
|
|
477
|
+
return void 0;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
};
|
|
342
481
|
|
|
343
482
|
// ../../node_modules/@probe.gl/log/dist/utils/local-storage.js
|
|
344
483
|
function getStorage(type) {
|
|
@@ -457,13 +596,6 @@ var __exports__ = (() => {
|
|
|
457
596
|
}
|
|
458
597
|
}
|
|
459
598
|
|
|
460
|
-
// ../../node_modules/@probe.gl/log/dist/utils/assert.js
|
|
461
|
-
function assert(condition, message) {
|
|
462
|
-
if (!condition) {
|
|
463
|
-
throw new Error(message || "Assertion failed");
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
|
|
467
599
|
// ../../node_modules/@probe.gl/log/dist/utils/hi-res-timestamp.js
|
|
468
600
|
function getHiResTimestamp2() {
|
|
469
601
|
let timestamp;
|
|
@@ -478,7 +610,7 @@ var __exports__ = (() => {
|
|
|
478
610
|
return timestamp;
|
|
479
611
|
}
|
|
480
612
|
|
|
481
|
-
// ../../node_modules/@probe.gl/log/dist/log.js
|
|
613
|
+
// ../../node_modules/@probe.gl/log/dist/loggers/probe-log.js
|
|
482
614
|
var originalConsole = {
|
|
483
615
|
debug: isBrowser() ? console.debug || console.log : console.log,
|
|
484
616
|
log: console.log,
|
|
@@ -490,12 +622,9 @@ var __exports__ = (() => {
|
|
|
490
622
|
enabled: true,
|
|
491
623
|
level: 0
|
|
492
624
|
};
|
|
493
|
-
|
|
494
|
-
}
|
|
495
|
-
var cache = {};
|
|
496
|
-
var ONCE = { once: true };
|
|
497
|
-
var Log = class {
|
|
625
|
+
var ProbeLog = class extends BaseLog {
|
|
498
626
|
constructor({ id } = { id: "" }) {
|
|
627
|
+
super({ level: 0 });
|
|
499
628
|
this.VERSION = VERSION;
|
|
500
629
|
this._startTs = getHiResTimestamp2();
|
|
501
630
|
this._deltaTs = getHiResTimestamp2();
|
|
@@ -503,22 +632,16 @@ var __exports__ = (() => {
|
|
|
503
632
|
this.LOG_THROTTLE_TIMEOUT = 0;
|
|
504
633
|
this.id = id;
|
|
505
634
|
this.userData = {};
|
|
506
|
-
this._storage = new LocalStorage(`__probe-${this.id}__`, DEFAULT_LOG_CONFIGURATION);
|
|
635
|
+
this._storage = new LocalStorage(`__probe-${this.id}__`, { [this.id]: DEFAULT_LOG_CONFIGURATION });
|
|
507
636
|
this.timeStamp(`${this.id} started`);
|
|
508
637
|
autobind(this);
|
|
509
638
|
Object.seal(this);
|
|
510
639
|
}
|
|
511
|
-
set level(newLevel) {
|
|
512
|
-
this.setLevel(newLevel);
|
|
513
|
-
}
|
|
514
|
-
get level() {
|
|
515
|
-
return this.getLevel();
|
|
516
|
-
}
|
|
517
640
|
isEnabled() {
|
|
518
|
-
return this.
|
|
641
|
+
return this._getConfiguration().enabled;
|
|
519
642
|
}
|
|
520
643
|
getLevel() {
|
|
521
|
-
return this.
|
|
644
|
+
return this._getConfiguration().level;
|
|
522
645
|
}
|
|
523
646
|
/** @return milliseconds, with fractions */
|
|
524
647
|
getTotal() {
|
|
@@ -542,20 +665,20 @@ var __exports__ = (() => {
|
|
|
542
665
|
}
|
|
543
666
|
// Configure
|
|
544
667
|
enable(enabled = true) {
|
|
545
|
-
this.
|
|
668
|
+
this._updateConfiguration({ enabled });
|
|
546
669
|
return this;
|
|
547
670
|
}
|
|
548
671
|
setLevel(level) {
|
|
549
|
-
this.
|
|
672
|
+
this._updateConfiguration({ level });
|
|
550
673
|
return this;
|
|
551
674
|
}
|
|
552
675
|
/** return the current status of the setting */
|
|
553
676
|
get(setting) {
|
|
554
|
-
return this.
|
|
677
|
+
return this._getConfiguration()[setting];
|
|
555
678
|
}
|
|
556
679
|
// update the status of the setting
|
|
557
680
|
set(setting, value) {
|
|
558
|
-
this.
|
|
681
|
+
this._updateConfiguration({ [setting]: value });
|
|
559
682
|
}
|
|
560
683
|
/** Logs the current settings as a table */
|
|
561
684
|
settings() {
|
|
@@ -571,11 +694,16 @@ var __exports__ = (() => {
|
|
|
571
694
|
throw new Error(message || "Assertion failed");
|
|
572
695
|
}
|
|
573
696
|
}
|
|
574
|
-
warn(message) {
|
|
575
|
-
return this.
|
|
697
|
+
warn(message, ...args) {
|
|
698
|
+
return this._log("warn", 0, message, args, {
|
|
699
|
+
method: originalConsole.warn,
|
|
700
|
+
once: true
|
|
701
|
+
});
|
|
576
702
|
}
|
|
577
|
-
error(message) {
|
|
578
|
-
return this.
|
|
703
|
+
error(message, ...args) {
|
|
704
|
+
return this._log("error", 0, message, args, {
|
|
705
|
+
method: originalConsole.error
|
|
706
|
+
});
|
|
579
707
|
}
|
|
580
708
|
/** Print a deprecation warning */
|
|
581
709
|
deprecated(oldUsage, newUsage) {
|
|
@@ -585,50 +713,63 @@ var __exports__ = (() => {
|
|
|
585
713
|
removed(oldUsage, newUsage) {
|
|
586
714
|
return this.error(`\`${oldUsage}\` has been removed. Use \`${newUsage}\` instead`);
|
|
587
715
|
}
|
|
588
|
-
probe(logLevel, message) {
|
|
589
|
-
return this.
|
|
716
|
+
probe(logLevel, message, ...args) {
|
|
717
|
+
return this._log("log", logLevel, message, args, {
|
|
718
|
+
method: originalConsole.log,
|
|
590
719
|
time: true,
|
|
591
720
|
once: true
|
|
592
721
|
});
|
|
593
722
|
}
|
|
594
|
-
log(logLevel, message) {
|
|
595
|
-
return this.
|
|
723
|
+
log(logLevel, message, ...args) {
|
|
724
|
+
return this._log("log", logLevel, message, args, {
|
|
725
|
+
method: originalConsole.debug
|
|
726
|
+
});
|
|
596
727
|
}
|
|
597
|
-
info(logLevel, message) {
|
|
598
|
-
return this.
|
|
728
|
+
info(logLevel, message, ...args) {
|
|
729
|
+
return this._log("info", logLevel, message, args, { method: console.info });
|
|
599
730
|
}
|
|
600
|
-
once(logLevel, message) {
|
|
601
|
-
return this.
|
|
731
|
+
once(logLevel, message, ...args) {
|
|
732
|
+
return this._log("once", logLevel, message, args, {
|
|
733
|
+
method: originalConsole.debug || originalConsole.info,
|
|
734
|
+
once: true
|
|
735
|
+
});
|
|
602
736
|
}
|
|
603
737
|
/** Logs an object as a table */
|
|
604
738
|
table(logLevel, table, columns) {
|
|
605
739
|
if (table) {
|
|
606
|
-
return this.
|
|
740
|
+
return this._log("table", logLevel, table, columns && [columns] || [], {
|
|
741
|
+
method: console.table || noop,
|
|
607
742
|
tag: getTableHeader(table)
|
|
608
743
|
});
|
|
609
744
|
}
|
|
610
745
|
return noop;
|
|
611
746
|
}
|
|
612
747
|
time(logLevel, message) {
|
|
613
|
-
return this.
|
|
748
|
+
return this._log("time", logLevel, message, [], {
|
|
749
|
+
method: console.time ? console.time : console.info
|
|
750
|
+
});
|
|
614
751
|
}
|
|
615
752
|
timeEnd(logLevel, message) {
|
|
616
|
-
return this.
|
|
753
|
+
return this._log("time", logLevel, message, [], {
|
|
754
|
+
method: console.timeEnd ? console.timeEnd : console.info
|
|
755
|
+
});
|
|
617
756
|
}
|
|
618
757
|
timeStamp(logLevel, message) {
|
|
619
|
-
return this.
|
|
758
|
+
return this._log("time", logLevel, message, [], {
|
|
759
|
+
method: console.timeStamp || noop
|
|
760
|
+
});
|
|
620
761
|
}
|
|
621
762
|
group(logLevel, message, opts = { collapsed: false }) {
|
|
622
|
-
const
|
|
623
|
-
|
|
624
|
-
options.method = (collapsed ? console.groupCollapsed : console.group) || console.info;
|
|
625
|
-
return this._getLogFunction(options);
|
|
763
|
+
const method = (opts.collapsed ? console.groupCollapsed : console.group) || console.info;
|
|
764
|
+
return this._log("group", logLevel, message, [], { method });
|
|
626
765
|
}
|
|
627
766
|
groupCollapsed(logLevel, message, opts = {}) {
|
|
628
767
|
return this.group(logLevel, message, Object.assign({}, opts, { collapsed: true }));
|
|
629
768
|
}
|
|
630
769
|
groupEnd(logLevel) {
|
|
631
|
-
return this.
|
|
770
|
+
return this._log("groupEnd", logLevel, "", [], {
|
|
771
|
+
method: console.groupEnd || noop
|
|
772
|
+
});
|
|
632
773
|
}
|
|
633
774
|
// EXPERIMENTAL
|
|
634
775
|
withGroup(logLevel, message, func) {
|
|
@@ -644,78 +785,34 @@ var __exports__ = (() => {
|
|
|
644
785
|
console.trace();
|
|
645
786
|
}
|
|
646
787
|
}
|
|
647
|
-
// PRIVATE METHODS
|
|
648
|
-
/** Deduces log level from a variety of arguments */
|
|
649
788
|
_shouldLog(logLevel) {
|
|
650
|
-
return this.isEnabled() &&
|
|
651
|
-
}
|
|
652
|
-
_getLogFunction(logLevel, message, method, args, opts) {
|
|
653
|
-
if (this._shouldLog(logLevel)) {
|
|
654
|
-
opts = normalizeArguments({ logLevel, message, args, opts });
|
|
655
|
-
method = method || opts.method;
|
|
656
|
-
assert(method);
|
|
657
|
-
opts.total = this.getTotal();
|
|
658
|
-
opts.delta = this.getDelta();
|
|
659
|
-
this._deltaTs = getHiResTimestamp2();
|
|
660
|
-
const tag = opts.tag || opts.message;
|
|
661
|
-
if (opts.once && tag) {
|
|
662
|
-
if (!cache[tag]) {
|
|
663
|
-
cache[tag] = getHiResTimestamp2();
|
|
664
|
-
} else {
|
|
665
|
-
return noop;
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
message = decorateMessage(this.id, opts.message, opts);
|
|
669
|
-
return method.bind(console, message, ...opts.args);
|
|
670
|
-
}
|
|
671
|
-
return noop;
|
|
672
|
-
}
|
|
673
|
-
};
|
|
674
|
-
Log.VERSION = VERSION;
|
|
675
|
-
function normalizeLogLevel(logLevel) {
|
|
676
|
-
if (!logLevel) {
|
|
677
|
-
return 0;
|
|
678
|
-
}
|
|
679
|
-
let resolvedLevel;
|
|
680
|
-
switch (typeof logLevel) {
|
|
681
|
-
case "number":
|
|
682
|
-
resolvedLevel = logLevel;
|
|
683
|
-
break;
|
|
684
|
-
case "object":
|
|
685
|
-
resolvedLevel = logLevel.logLevel || logLevel.priority || 0;
|
|
686
|
-
break;
|
|
687
|
-
default:
|
|
688
|
-
return 0;
|
|
789
|
+
return this.isEnabled() && super._shouldLog(logLevel);
|
|
689
790
|
}
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
791
|
+
_emit(_type, normalized) {
|
|
792
|
+
const method = normalized.method;
|
|
793
|
+
assert(method);
|
|
794
|
+
normalized.total = this.getTotal();
|
|
795
|
+
normalized.delta = this.getDelta();
|
|
796
|
+
this._deltaTs = getHiResTimestamp2();
|
|
797
|
+
const message = decorateMessage(this.id, normalized.message, normalized);
|
|
798
|
+
return method.bind(console, message, ...normalized.args);
|
|
698
799
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
}
|
|
705
|
-
opts.message = logLevel;
|
|
706
|
-
break;
|
|
707
|
-
case "object":
|
|
708
|
-
Object.assign(opts, logLevel);
|
|
709
|
-
break;
|
|
710
|
-
default:
|
|
800
|
+
_getConfiguration() {
|
|
801
|
+
if (!this._storage.config[this.id]) {
|
|
802
|
+
this._updateConfiguration(DEFAULT_LOG_CONFIGURATION);
|
|
803
|
+
}
|
|
804
|
+
return this._storage.config[this.id];
|
|
711
805
|
}
|
|
712
|
-
|
|
713
|
-
|
|
806
|
+
_updateConfiguration(configuration) {
|
|
807
|
+
const currentConfiguration = this._storage.config[this.id] || {
|
|
808
|
+
...DEFAULT_LOG_CONFIGURATION
|
|
809
|
+
};
|
|
810
|
+
this._storage.setConfiguration({
|
|
811
|
+
[this.id]: { ...currentConfiguration, ...configuration }
|
|
812
|
+
});
|
|
714
813
|
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
return Object.assign(opts, { args }, opts.opts);
|
|
718
|
-
}
|
|
814
|
+
};
|
|
815
|
+
ProbeLog.VERSION = VERSION;
|
|
719
816
|
function decorateMessage(id, message, opts) {
|
|
720
817
|
if (typeof message === "string") {
|
|
721
818
|
const time = opts.time ? leftPad(formatTime(opts.total)) : "";
|
|
@@ -737,10 +834,10 @@ var __exports__ = (() => {
|
|
|
737
834
|
globalThis.probe = {};
|
|
738
835
|
|
|
739
836
|
// ../../node_modules/@probe.gl/log/dist/index.js
|
|
740
|
-
var dist_default = new
|
|
837
|
+
var dist_default = new ProbeLog({ id: "@probe.gl/log" });
|
|
741
838
|
|
|
742
839
|
// ../core/src/utils/log.ts
|
|
743
|
-
var log = new
|
|
840
|
+
var log = new ProbeLog({ id: "luma.gl" });
|
|
744
841
|
|
|
745
842
|
// ../core/src/utils/uid.ts
|
|
746
843
|
var uidCounters = {};
|
|
@@ -757,8 +854,11 @@ var __exports__ = (() => {
|
|
|
757
854
|
}
|
|
758
855
|
/** props.id, for debugging. */
|
|
759
856
|
id;
|
|
857
|
+
/** The props that this resource was created with */
|
|
760
858
|
props;
|
|
859
|
+
/** User data object, reserved for the application */
|
|
761
860
|
userData = {};
|
|
861
|
+
/** The device that this resource is associated with - TODO can we remove this dup? */
|
|
762
862
|
_device;
|
|
763
863
|
/** Whether this resource has been destroyed */
|
|
764
864
|
destroyed = false;
|
|
@@ -965,10 +1065,11 @@ var __exports__ = (() => {
|
|
|
965
1065
|
|
|
966
1066
|
// ../core/src/shadertypes/data-types/decode-data-types.ts
|
|
967
1067
|
function getDataTypeInfo(type) {
|
|
968
|
-
const [signedType, primitiveType, byteLength] = NORMALIZED_TYPE_MAP[type];
|
|
969
1068
|
const normalized = type.includes("norm");
|
|
970
1069
|
const integer = !normalized && !type.startsWith("float");
|
|
971
1070
|
const signed = type.startsWith("s");
|
|
1071
|
+
const typeInfo = NORMALIZED_TYPE_MAP[type];
|
|
1072
|
+
const [signedType, primitiveType, byteLength] = typeInfo || ["uint8 ", "i32", 1];
|
|
972
1073
|
return {
|
|
973
1074
|
signedType,
|
|
974
1075
|
primitiveType,
|
|
@@ -1284,6 +1385,9 @@ var __exports__ = (() => {
|
|
|
1284
1385
|
};
|
|
1285
1386
|
|
|
1286
1387
|
// ../core/src/shadertypes/textures/texture-format-decoder.ts
|
|
1388
|
+
var RGB_FORMAT_REGEX = /^(r|rg|rgb|rgba|bgra)([0-9]*)([a-z]*)(-srgb)?(-webgl)?$/;
|
|
1389
|
+
var COLOR_FORMAT_PREFIXES = ["rgb", "rgba", "bgra"];
|
|
1390
|
+
var DEPTH_FORMAT_PREFIXES = ["depth", "stencil"];
|
|
1287
1391
|
var COMPRESSED_TEXTURE_FORMAT_PREFIXES = [
|
|
1288
1392
|
"bc1",
|
|
1289
1393
|
"bc2",
|
|
@@ -1299,49 +1403,73 @@ var __exports__ = (() => {
|
|
|
1299
1403
|
"astc",
|
|
1300
1404
|
"pvrtc"
|
|
1301
1405
|
];
|
|
1302
|
-
var RGB_FORMAT_REGEX = /^(r|rg|rgb|rgba|bgra)([0-9]*)([a-z]*)(-srgb)?(-webgl)?$/;
|
|
1303
1406
|
var TextureFormatDecoder = class {
|
|
1304
|
-
/** Returns information about a texture format, e.g. attatchment type, components, byte length and flags (integer, signed, normalized) */
|
|
1305
|
-
getInfo(format) {
|
|
1306
|
-
return getTextureFormatInfo(format);
|
|
1307
|
-
}
|
|
1308
1407
|
/** Checks if a texture format is color */
|
|
1309
1408
|
isColor(format) {
|
|
1310
|
-
return
|
|
1409
|
+
return COLOR_FORMAT_PREFIXES.some((prefix) => format.startsWith(prefix));
|
|
1311
1410
|
}
|
|
1312
1411
|
/** Checks if a texture format is depth or stencil */
|
|
1313
1412
|
isDepthStencil(format) {
|
|
1314
|
-
return
|
|
1413
|
+
return DEPTH_FORMAT_PREFIXES.some((prefix) => format.startsWith(prefix));
|
|
1315
1414
|
}
|
|
1316
1415
|
/** Checks if a texture format is compressed */
|
|
1317
1416
|
isCompressed(format) {
|
|
1318
1417
|
return COMPRESSED_TEXTURE_FORMAT_PREFIXES.some((prefix) => format.startsWith(prefix));
|
|
1319
1418
|
}
|
|
1320
|
-
/**
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1419
|
+
/** Returns information about a texture format, e.g. attachment type, components, byte length and flags (integer, signed, normalized) */
|
|
1420
|
+
getInfo(format) {
|
|
1421
|
+
return getTextureFormatInfo(format);
|
|
1422
|
+
}
|
|
1423
|
+
/** "static" capabilities of a texture format. @note Needs to be adjusted against current device */
|
|
1324
1424
|
getCapabilities(format) {
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
filter: info.filter ?? true,
|
|
1331
|
-
blend: info.blend ?? true,
|
|
1332
|
-
store: info.store ?? true
|
|
1333
|
-
};
|
|
1334
|
-
const formatInfo = getTextureFormatInfo(format);
|
|
1335
|
-
const isDepthStencil = format.startsWith("depth") || format.startsWith("stencil");
|
|
1336
|
-
const isSigned = formatInfo?.signed;
|
|
1337
|
-
const isInteger = formatInfo?.integer;
|
|
1338
|
-
const isWebGLSpecific = formatInfo?.webgl;
|
|
1339
|
-
formatCapabilities.render &&= !isSigned;
|
|
1340
|
-
formatCapabilities.filter &&= !isDepthStencil && !isSigned && !isInteger && !isWebGLSpecific;
|
|
1341
|
-
return formatCapabilities;
|
|
1425
|
+
return getTextureFormatCapabilities(format);
|
|
1426
|
+
}
|
|
1427
|
+
/** Computes the memory layout for a texture, in particular including row byte alignment */
|
|
1428
|
+
computeMemoryLayout(opts) {
|
|
1429
|
+
return computeTextureMemoryLayout(opts);
|
|
1342
1430
|
}
|
|
1343
1431
|
};
|
|
1344
1432
|
var textureFormatDecoder = new TextureFormatDecoder();
|
|
1433
|
+
function computeTextureMemoryLayout({
|
|
1434
|
+
format,
|
|
1435
|
+
width,
|
|
1436
|
+
height,
|
|
1437
|
+
depth,
|
|
1438
|
+
byteAlignment
|
|
1439
|
+
}) {
|
|
1440
|
+
const { bytesPerPixel } = textureFormatDecoder.getInfo(format);
|
|
1441
|
+
const unpaddedBytesPerRow = width * bytesPerPixel;
|
|
1442
|
+
const bytesPerRow = Math.ceil(unpaddedBytesPerRow / byteAlignment) * byteAlignment;
|
|
1443
|
+
const rowsPerImage = height;
|
|
1444
|
+
const byteLength = bytesPerRow * rowsPerImage * depth;
|
|
1445
|
+
return {
|
|
1446
|
+
bytesPerPixel,
|
|
1447
|
+
bytesPerRow,
|
|
1448
|
+
rowsPerImage,
|
|
1449
|
+
depthOrArrayLayers: depth,
|
|
1450
|
+
bytesPerImage: bytesPerRow * rowsPerImage,
|
|
1451
|
+
byteLength
|
|
1452
|
+
};
|
|
1453
|
+
}
|
|
1454
|
+
function getTextureFormatCapabilities(format) {
|
|
1455
|
+
const info = getTextureFormatDefinition(format);
|
|
1456
|
+
const formatCapabilities = {
|
|
1457
|
+
format,
|
|
1458
|
+
create: info.f ?? true,
|
|
1459
|
+
render: info.render ?? true,
|
|
1460
|
+
filter: info.filter ?? true,
|
|
1461
|
+
blend: info.blend ?? true,
|
|
1462
|
+
store: info.store ?? true
|
|
1463
|
+
};
|
|
1464
|
+
const formatInfo = getTextureFormatInfo(format);
|
|
1465
|
+
const isDepthStencil = format.startsWith("depth") || format.startsWith("stencil");
|
|
1466
|
+
const isSigned = formatInfo?.signed;
|
|
1467
|
+
const isInteger = formatInfo?.integer;
|
|
1468
|
+
const isWebGLSpecific = formatInfo?.webgl;
|
|
1469
|
+
formatCapabilities.render &&= !isSigned;
|
|
1470
|
+
formatCapabilities.filter &&= !isDepthStencil && !isSigned && !isInteger && !isWebGLSpecific;
|
|
1471
|
+
return formatCapabilities;
|
|
1472
|
+
}
|
|
1345
1473
|
function getTextureFormatInfo(format) {
|
|
1346
1474
|
let formatInfo = getTextureFormatInfoUsingTable(format);
|
|
1347
1475
|
if (textureFormatDecoder.isCompressed(format)) {
|
|
@@ -1362,7 +1490,7 @@ var __exports__ = (() => {
|
|
|
1362
1490
|
const dataType = `${type}${length}`;
|
|
1363
1491
|
const decodedType = getDataTypeInfo(dataType);
|
|
1364
1492
|
const bits = decodedType.byteLength * 8;
|
|
1365
|
-
const components = channels
|
|
1493
|
+
const components = channels?.length ?? 1;
|
|
1366
1494
|
const bitsPerChannel = [
|
|
1367
1495
|
bits,
|
|
1368
1496
|
components >= 2 ? bits : 0,
|
|
@@ -1379,7 +1507,7 @@ var __exports__ = (() => {
|
|
|
1379
1507
|
signed: decodedType.signed,
|
|
1380
1508
|
normalized: decodedType.normalized,
|
|
1381
1509
|
bitsPerChannel,
|
|
1382
|
-
bytesPerPixel: decodedType.byteLength *
|
|
1510
|
+
bytesPerPixel: decodedType.byteLength * components,
|
|
1383
1511
|
packed: formatInfo.packed,
|
|
1384
1512
|
srgb: formatInfo.srgb
|
|
1385
1513
|
};
|
|
@@ -1495,7 +1623,7 @@ var __exports__ = (() => {
|
|
|
1495
1623
|
/** True if this device has been reused during device creation (app has multiple references) */
|
|
1496
1624
|
_reused = false;
|
|
1497
1625
|
/** Used by other luma.gl modules to store data on the device */
|
|
1498
|
-
|
|
1626
|
+
_moduleData = {};
|
|
1499
1627
|
_textureCaps = {};
|
|
1500
1628
|
constructor(props) {
|
|
1501
1629
|
this.props = { ..._Device.defaultProps, ...props };
|
|
@@ -1592,7 +1720,13 @@ var __exports__ = (() => {
|
|
|
1592
1720
|
reportError(error, context, ...args) {
|
|
1593
1721
|
const isHandled = this.props.onError(error, context);
|
|
1594
1722
|
if (!isHandled) {
|
|
1595
|
-
return log.error(
|
|
1723
|
+
return log.error(
|
|
1724
|
+
this.type === "webgl" ? "%cWebGL" : "%cWebGPU",
|
|
1725
|
+
"color: white; background: red; padding: 2px 6px; border-radius: 3px;",
|
|
1726
|
+
error.message,
|
|
1727
|
+
context,
|
|
1728
|
+
...args
|
|
1729
|
+
);
|
|
1596
1730
|
}
|
|
1597
1731
|
return () => {
|
|
1598
1732
|
};
|
|
@@ -1614,6 +1748,10 @@ or create a device with the 'debug: true' prop.`;
|
|
|
1614
1748
|
}
|
|
1615
1749
|
return this.canvasContext;
|
|
1616
1750
|
}
|
|
1751
|
+
/** Create a fence sync object */
|
|
1752
|
+
createFence() {
|
|
1753
|
+
throw new Error("createFence() not implemented");
|
|
1754
|
+
}
|
|
1617
1755
|
/** Create a RenderPass using the default CommandEncoder */
|
|
1618
1756
|
beginRenderPass(props) {
|
|
1619
1757
|
return this.commandEncoder.beginRenderPass(props);
|
|
@@ -1657,6 +1795,12 @@ or create a device with the 'debug: true' prop.`;
|
|
|
1657
1795
|
resetWebGL() {
|
|
1658
1796
|
throw new Error("not implemented");
|
|
1659
1797
|
}
|
|
1798
|
+
// INTERNAL LUMA.GL METHODS
|
|
1799
|
+
getModuleData(moduleName) {
|
|
1800
|
+
this._moduleData[moduleName] ||= {};
|
|
1801
|
+
return this._moduleData[moduleName];
|
|
1802
|
+
}
|
|
1803
|
+
// INTERNAL HELPERS
|
|
1660
1804
|
// IMPLEMENTATION
|
|
1661
1805
|
/** Helper to get the canvas context props */
|
|
1662
1806
|
static _getCanvasContextProps(props) {
|
|
@@ -1933,6 +2077,19 @@ or create a device with the 'debug: true' prop.`;
|
|
|
1933
2077
|
return { promise, resolve, reject };
|
|
1934
2078
|
}
|
|
1935
2079
|
|
|
2080
|
+
// ../core/src/utils/assert.ts
|
|
2081
|
+
function assert2(condition, message) {
|
|
2082
|
+
if (!condition) {
|
|
2083
|
+
const error = new Error(message ?? "luma.gl assertion failed.");
|
|
2084
|
+
Error.captureStackTrace?.(error, assert2);
|
|
2085
|
+
throw error;
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
function assertDefined(value, message) {
|
|
2089
|
+
assert2(value, message);
|
|
2090
|
+
return value;
|
|
2091
|
+
}
|
|
2092
|
+
|
|
1936
2093
|
// ../core/src/adapter/canvas-context.ts
|
|
1937
2094
|
var _CanvasContext = class {
|
|
1938
2095
|
static isHTMLCanvas(canvas) {
|
|
@@ -1968,11 +2125,19 @@ or create a device with the 'debug: true' prop.`;
|
|
|
1968
2125
|
drawingBufferWidth;
|
|
1969
2126
|
/** Height of drawing buffer: automatically tracks this.pixelHeight if props.autoResize is true */
|
|
1970
2127
|
drawingBufferHeight;
|
|
2128
|
+
/** Resolves when the canvas is initialized, i.e. when the ResizeObserver has updated the pixel size */
|
|
1971
2129
|
_initializedResolvers = withResolvers();
|
|
2130
|
+
/** ResizeObserver to track canvas size changes */
|
|
1972
2131
|
_resizeObserver;
|
|
2132
|
+
/** IntersectionObserver to track canvas visibility changes */
|
|
1973
2133
|
_intersectionObserver;
|
|
1974
|
-
|
|
2134
|
+
_observeDevicePixelRatioTimeout = null;
|
|
2135
|
+
/** Position of the canvas in the document, updated by a timer */
|
|
2136
|
+
_position = [0, 0];
|
|
2137
|
+
/** Whether this canvas context has been destroyed */
|
|
1975
2138
|
destroyed = false;
|
|
2139
|
+
/** Whether the drawing buffer size needs to be resized (deferred resizing to avoid flicker) */
|
|
2140
|
+
_needsDrawingBufferResize = true;
|
|
1976
2141
|
toString() {
|
|
1977
2142
|
return `${this[Symbol.toStringTag]}(${this.id})`;
|
|
1978
2143
|
}
|
|
@@ -2020,14 +2185,23 @@ or create a device with the 'debug: true' prop.`;
|
|
|
2020
2185
|
} catch {
|
|
2021
2186
|
this._resizeObserver.observe(this.canvas, { box: "content-box" });
|
|
2022
2187
|
}
|
|
2023
|
-
setTimeout(() => this._observeDevicePixelRatio(), 0);
|
|
2188
|
+
this._observeDevicePixelRatioTimeout = setTimeout(() => this._observeDevicePixelRatio(), 0);
|
|
2024
2189
|
if (this.props.trackPosition) {
|
|
2025
2190
|
this._trackPosition();
|
|
2026
2191
|
}
|
|
2027
2192
|
}
|
|
2028
2193
|
}
|
|
2029
2194
|
destroy() {
|
|
2030
|
-
this.destroyed
|
|
2195
|
+
if (!this.destroyed) {
|
|
2196
|
+
this.destroyed = true;
|
|
2197
|
+
if (this._observeDevicePixelRatioTimeout) {
|
|
2198
|
+
clearTimeout(this._observeDevicePixelRatioTimeout);
|
|
2199
|
+
this._observeDevicePixelRatioTimeout = null;
|
|
2200
|
+
}
|
|
2201
|
+
this.device = null;
|
|
2202
|
+
this._resizeObserver?.disconnect();
|
|
2203
|
+
this._intersectionObserver?.disconnect();
|
|
2204
|
+
}
|
|
2031
2205
|
}
|
|
2032
2206
|
setProps(props) {
|
|
2033
2207
|
if ("useDevicePixels" in props) {
|
|
@@ -2036,6 +2210,11 @@ or create a device with the 'debug: true' prop.`;
|
|
|
2036
2210
|
}
|
|
2037
2211
|
return this;
|
|
2038
2212
|
}
|
|
2213
|
+
/** Returns a framebuffer with properly resized current 'swap chain' textures */
|
|
2214
|
+
getCurrentFramebuffer(options) {
|
|
2215
|
+
this._resizeDrawingBufferIfNeeded();
|
|
2216
|
+
return this._getCurrentFramebuffer(options);
|
|
2217
|
+
}
|
|
2039
2218
|
// SIZE METHODS
|
|
2040
2219
|
/**
|
|
2041
2220
|
* Returns the size covered by the canvas in CSS pixels
|
|
@@ -2065,12 +2244,21 @@ or create a device with the 'debug: true' prop.`;
|
|
|
2065
2244
|
const maxTextureDimension = this.device.limits.maxTextureDimension2D;
|
|
2066
2245
|
return [maxTextureDimension, maxTextureDimension];
|
|
2067
2246
|
}
|
|
2068
|
-
/**
|
|
2247
|
+
/**
|
|
2248
|
+
* Update the canvas drawing buffer size.
|
|
2249
|
+
* @note - Called automatically if props.autoResize is true.
|
|
2250
|
+
* @note - Defers update of drawing buffer size until framebuffer is requested to avoid flicker
|
|
2251
|
+
* (resizing clears the drawing buffer)!
|
|
2252
|
+
*/
|
|
2069
2253
|
setDrawingBufferSize(width, height) {
|
|
2070
|
-
|
|
2071
|
-
|
|
2254
|
+
width = Math.floor(width);
|
|
2255
|
+
height = Math.floor(height);
|
|
2256
|
+
if (this.drawingBufferWidth === width && this.drawingBufferHeight === height) {
|
|
2257
|
+
return;
|
|
2258
|
+
}
|
|
2072
2259
|
this.drawingBufferWidth = width;
|
|
2073
2260
|
this.drawingBufferHeight = height;
|
|
2261
|
+
this._needsDrawingBufferResize = true;
|
|
2074
2262
|
}
|
|
2075
2263
|
/**
|
|
2076
2264
|
* Returns the current DPR (number of physical pixels per CSS pixel), if props.useDevicePixels is true
|
|
@@ -2125,6 +2313,9 @@ or create a device with the 'debug: true' prop.`;
|
|
|
2125
2313
|
}
|
|
2126
2314
|
/** reacts to an observed intersection */
|
|
2127
2315
|
_handleIntersection(entries) {
|
|
2316
|
+
if (this.destroyed) {
|
|
2317
|
+
return;
|
|
2318
|
+
}
|
|
2128
2319
|
const entry = entries.find((entry_) => entry_.target === this.canvas);
|
|
2129
2320
|
if (!entry) {
|
|
2130
2321
|
return;
|
|
@@ -2141,21 +2332,26 @@ or create a device with the 'debug: true' prop.`;
|
|
|
2141
2332
|
* @see https://webgpufundamentals.org/webgpu/lessons/webgpu-resizing-the-canvas.html
|
|
2142
2333
|
*/
|
|
2143
2334
|
_handleResize(entries) {
|
|
2335
|
+
if (this.destroyed) {
|
|
2336
|
+
return;
|
|
2337
|
+
}
|
|
2144
2338
|
const entry = entries.find((entry_) => entry_.target === this.canvas);
|
|
2145
2339
|
if (!entry) {
|
|
2146
2340
|
return;
|
|
2147
2341
|
}
|
|
2148
|
-
|
|
2149
|
-
this.
|
|
2342
|
+
const contentBoxSize = assertDefined(entry.contentBoxSize?.[0]);
|
|
2343
|
+
this.cssWidth = contentBoxSize.inlineSize;
|
|
2344
|
+
this.cssHeight = contentBoxSize.blockSize;
|
|
2150
2345
|
const oldPixelSize = this.getDevicePixelSize();
|
|
2151
|
-
const devicePixelWidth = entry.devicePixelContentBoxSize?.[0]
|
|
2152
|
-
const devicePixelHeight = entry.devicePixelContentBoxSize?.[0]
|
|
2346
|
+
const devicePixelWidth = entry.devicePixelContentBoxSize?.[0]?.inlineSize || contentBoxSize.inlineSize * devicePixelRatio;
|
|
2347
|
+
const devicePixelHeight = entry.devicePixelContentBoxSize?.[0]?.blockSize || contentBoxSize.blockSize * devicePixelRatio;
|
|
2153
2348
|
const [maxDevicePixelWidth, maxDevicePixelHeight] = this.getMaxDrawingBufferSize();
|
|
2154
2349
|
this.devicePixelWidth = Math.max(1, Math.min(devicePixelWidth, maxDevicePixelWidth));
|
|
2155
2350
|
this.devicePixelHeight = Math.max(1, Math.min(devicePixelHeight, maxDevicePixelHeight));
|
|
2156
2351
|
this._updateDrawingBufferSize();
|
|
2157
2352
|
this.device.props.onResize(this, { oldPixelSize });
|
|
2158
2353
|
}
|
|
2354
|
+
/** Initiate a deferred update for the canvas drawing buffer size */
|
|
2159
2355
|
_updateDrawingBufferSize() {
|
|
2160
2356
|
if (this.props.autoResize) {
|
|
2161
2357
|
if (typeof this.props.useDevicePixels === "number") {
|
|
@@ -2166,18 +2362,32 @@ or create a device with the 'debug: true' prop.`;
|
|
|
2166
2362
|
} else {
|
|
2167
2363
|
this.setDrawingBufferSize(this.cssWidth, this.cssHeight);
|
|
2168
2364
|
}
|
|
2169
|
-
this._updateDevice();
|
|
2170
2365
|
}
|
|
2171
2366
|
this._initializedResolvers.resolve();
|
|
2172
2367
|
this.isInitialized = true;
|
|
2173
2368
|
this.updatePosition();
|
|
2174
2369
|
}
|
|
2370
|
+
/** Perform a deferred resize of the drawing buffer if needed */
|
|
2371
|
+
_resizeDrawingBufferIfNeeded() {
|
|
2372
|
+
if (this._needsDrawingBufferResize) {
|
|
2373
|
+
this._needsDrawingBufferResize = false;
|
|
2374
|
+
const sizeChanged = this.drawingBufferWidth !== this.canvas.width || this.drawingBufferHeight !== this.canvas.height;
|
|
2375
|
+
if (sizeChanged) {
|
|
2376
|
+
this.canvas.width = this.drawingBufferWidth;
|
|
2377
|
+
this.canvas.height = this.drawingBufferHeight;
|
|
2378
|
+
this._configureDevice();
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2175
2382
|
/** Monitor DPR changes */
|
|
2176
2383
|
_observeDevicePixelRatio() {
|
|
2384
|
+
if (this.destroyed) {
|
|
2385
|
+
return;
|
|
2386
|
+
}
|
|
2177
2387
|
const oldRatio = this.devicePixelRatio;
|
|
2178
2388
|
this.devicePixelRatio = window.devicePixelRatio;
|
|
2179
2389
|
this.updatePosition();
|
|
2180
|
-
this.device.props.onDevicePixelRatioChange(this, { oldRatio });
|
|
2390
|
+
this.device.props.onDevicePixelRatioChange?.(this, { oldRatio });
|
|
2181
2391
|
matchMedia(`(resolution: ${this.devicePixelRatio}dppx)`).addEventListener(
|
|
2182
2392
|
"change",
|
|
2183
2393
|
() => this._observeDevicePixelRatio(),
|
|
@@ -2200,6 +2410,9 @@ or create a device with the 'debug: true' prop.`;
|
|
|
2200
2410
|
* if called before browser has finished a reflow. Should not be the case here.
|
|
2201
2411
|
*/
|
|
2202
2412
|
updatePosition() {
|
|
2413
|
+
if (this.destroyed) {
|
|
2414
|
+
return;
|
|
2415
|
+
}
|
|
2203
2416
|
const newRect = this.htmlCanvas?.getBoundingClientRect();
|
|
2204
2417
|
if (newRect) {
|
|
2205
2418
|
const position = [newRect.left, newRect.top];
|
|
@@ -2347,7 +2560,13 @@ or create a device with the 'debug: true' prop.`;
|
|
|
2347
2560
|
depth;
|
|
2348
2561
|
/** mip levels in this texture */
|
|
2349
2562
|
mipLevels;
|
|
2350
|
-
/**
|
|
2563
|
+
/** Rows are multiples of this length, padded with extra bytes if needed */
|
|
2564
|
+
byteAlignment;
|
|
2565
|
+
/** The ready promise is always resolved. It is provided for type compatibility with DynamicTexture. */
|
|
2566
|
+
ready = Promise.resolve(this);
|
|
2567
|
+
/** isReady is always true. It is provided for type compatibility with DynamicTexture. */
|
|
2568
|
+
isReady = true;
|
|
2569
|
+
/** "Time" of last update. Monotonically increasing timestamp. TODO move to DynamicTexture? */
|
|
2351
2570
|
updateTimestamp;
|
|
2352
2571
|
get [Symbol.toStringTag]() {
|
|
2353
2572
|
return "Texture";
|
|
@@ -2356,7 +2575,7 @@ or create a device with the 'debug: true' prop.`;
|
|
|
2356
2575
|
return `Texture(${this.id},${this.format},${this.width}x${this.height})`;
|
|
2357
2576
|
}
|
|
2358
2577
|
/** Do not use directly. Create with device.createTexture() */
|
|
2359
|
-
constructor(device, props) {
|
|
2578
|
+
constructor(device, props, backendProps) {
|
|
2360
2579
|
props = _Texture.normalizeProps(device, props);
|
|
2361
2580
|
super(device, props, _Texture.defaultProps);
|
|
2362
2581
|
this.dimension = this.props.dimension;
|
|
@@ -2366,6 +2585,9 @@ or create a device with the 'debug: true' prop.`;
|
|
|
2366
2585
|
this.height = this.props.height;
|
|
2367
2586
|
this.depth = this.props.depth;
|
|
2368
2587
|
this.mipLevels = this.props.mipLevels;
|
|
2588
|
+
if (this.dimension === "cube") {
|
|
2589
|
+
this.depth = 6;
|
|
2590
|
+
}
|
|
2369
2591
|
if (this.props.width === void 0 || this.props.height === void 0) {
|
|
2370
2592
|
if (device.isExternalImage(props.data)) {
|
|
2371
2593
|
const size = device.getExternalImageSize(props.data);
|
|
@@ -2376,17 +2598,14 @@ or create a device with the 'debug: true' prop.`;
|
|
|
2376
2598
|
this.height = 1;
|
|
2377
2599
|
if (this.props.width === void 0 || this.props.height === void 0) {
|
|
2378
2600
|
log.warn(
|
|
2379
|
-
`${this} created with undefined width or height. This is deprecated. Use
|
|
2601
|
+
`${this} created with undefined width or height. This is deprecated. Use DynamicTexture instead.`
|
|
2380
2602
|
)();
|
|
2381
2603
|
}
|
|
2382
2604
|
}
|
|
2383
2605
|
}
|
|
2606
|
+
this.byteAlignment = backendProps?.byteAlignment || 1;
|
|
2384
2607
|
this.updateTimestamp = device.incrementTimestamp();
|
|
2385
2608
|
}
|
|
2386
|
-
/** Set sampler props associated with this texture */
|
|
2387
|
-
setSampler(sampler) {
|
|
2388
|
-
this.sampler = sampler instanceof Sampler ? sampler : this.device.createSampler(sampler);
|
|
2389
|
-
}
|
|
2390
2609
|
/**
|
|
2391
2610
|
* Create a new texture with the same parameters and optionally a different size
|
|
2392
2611
|
* @note Textures are immutable and cannot be resized after creation, but we can create a similar texture with the same parameters but a new size.
|
|
@@ -2395,6 +2614,79 @@ or create a device with the 'debug: true' prop.`;
|
|
|
2395
2614
|
clone(size) {
|
|
2396
2615
|
return this.device.createTexture({ ...this.props, ...size });
|
|
2397
2616
|
}
|
|
2617
|
+
/** Set sampler props associated with this texture */
|
|
2618
|
+
setSampler(sampler) {
|
|
2619
|
+
this.sampler = sampler instanceof Sampler ? sampler : this.device.createSampler(sampler);
|
|
2620
|
+
}
|
|
2621
|
+
/**
|
|
2622
|
+
* Calculates the memory layout of the texture, required when reading and writing data.
|
|
2623
|
+
* @return the memory layout of the texture, in particular bytesPerRow which includes required padding
|
|
2624
|
+
*/
|
|
2625
|
+
computeMemoryLayout(options_ = {}) {
|
|
2626
|
+
const options = this._normalizeTextureReadOptions(options_);
|
|
2627
|
+
const { width = this.width, height = this.height, depthOrArrayLayers = this.depth } = options;
|
|
2628
|
+
const { format, byteAlignment } = this;
|
|
2629
|
+
return textureFormatDecoder.computeMemoryLayout({
|
|
2630
|
+
format,
|
|
2631
|
+
width,
|
|
2632
|
+
height,
|
|
2633
|
+
depth: depthOrArrayLayers,
|
|
2634
|
+
byteAlignment
|
|
2635
|
+
});
|
|
2636
|
+
}
|
|
2637
|
+
/**
|
|
2638
|
+
* Read the contents of a texture into a GPU Buffer.
|
|
2639
|
+
* @returns A Buffer containing the texture data.
|
|
2640
|
+
*
|
|
2641
|
+
* @note The memory layout of the texture data is determined by the texture format and dimensions.
|
|
2642
|
+
* @note The application can call Texture.computeMemoryLayout() to compute the layout.
|
|
2643
|
+
* @note The application can call Buffer.readAsync()
|
|
2644
|
+
* @note If not supplied a buffer will be created and the application needs to call Buffer.destroy
|
|
2645
|
+
*/
|
|
2646
|
+
readBuffer(options, buffer) {
|
|
2647
|
+
throw new Error("readBuffer not implemented");
|
|
2648
|
+
}
|
|
2649
|
+
/**
|
|
2650
|
+
* Reads data from a texture into an ArrayBuffer.
|
|
2651
|
+
* @returns An ArrayBuffer containing the texture data.
|
|
2652
|
+
*
|
|
2653
|
+
* @note The memory layout of the texture data is determined by the texture format and dimensions.
|
|
2654
|
+
* @note The application can call Texture.computeMemoryLayout() to compute the layout.
|
|
2655
|
+
*/
|
|
2656
|
+
readDataAsync(options) {
|
|
2657
|
+
throw new Error("readBuffer not implemented");
|
|
2658
|
+
}
|
|
2659
|
+
/**
|
|
2660
|
+
* Writes an GPU Buffer into a texture.
|
|
2661
|
+
*
|
|
2662
|
+
* @note The memory layout of the texture data is determined by the texture format and dimensions.
|
|
2663
|
+
* @note The application can call Texture.computeMemoryLayout() to compute the layout.
|
|
2664
|
+
*/
|
|
2665
|
+
writeBuffer(buffer, options) {
|
|
2666
|
+
throw new Error("readBuffer not implemented");
|
|
2667
|
+
}
|
|
2668
|
+
/**
|
|
2669
|
+
* Writes an array buffer into a texture.
|
|
2670
|
+
*
|
|
2671
|
+
* @note The memory layout of the texture data is determined by the texture format and dimensions.
|
|
2672
|
+
* @note The application can call Texture.computeMemoryLayout() to compute the layout.
|
|
2673
|
+
*/
|
|
2674
|
+
writeData(data, options) {
|
|
2675
|
+
throw new Error("readBuffer not implemented");
|
|
2676
|
+
}
|
|
2677
|
+
// IMPLEMENTATION SPECIFIC
|
|
2678
|
+
/**
|
|
2679
|
+
* WebGL can read data synchronously.
|
|
2680
|
+
* @note While it is convenient, the performance penalty is very significant
|
|
2681
|
+
*/
|
|
2682
|
+
readDataSyncWebGL(options) {
|
|
2683
|
+
throw new Error("readDataSyncWebGL not available");
|
|
2684
|
+
}
|
|
2685
|
+
/** Generate mipmaps (WebGL only) */
|
|
2686
|
+
generateMipmapsWebGL() {
|
|
2687
|
+
throw new Error("generateMipmapsWebGL not available");
|
|
2688
|
+
}
|
|
2689
|
+
// HELPERS
|
|
2398
2690
|
/** Ensure we have integer coordinates */
|
|
2399
2691
|
static normalizeProps(device, props) {
|
|
2400
2692
|
const newProps = { ...props };
|
|
@@ -2407,7 +2699,6 @@ or create a device with the 'debug: true' prop.`;
|
|
|
2407
2699
|
}
|
|
2408
2700
|
return newProps;
|
|
2409
2701
|
}
|
|
2410
|
-
// HELPERS
|
|
2411
2702
|
/** Initialize texture with supplied props */
|
|
2412
2703
|
// eslint-disable-next-line max-statements
|
|
2413
2704
|
_initializeData(data) {
|
|
@@ -2458,6 +2749,20 @@ or create a device with the 'debug: true' prop.`;
|
|
|
2458
2749
|
options.height = Math.min(options.height, this.height - options.y);
|
|
2459
2750
|
return options;
|
|
2460
2751
|
}
|
|
2752
|
+
_normalizeTextureReadOptions(options_) {
|
|
2753
|
+
const { width, height } = this;
|
|
2754
|
+
const options = { ..._Texture.defaultTextureReadOptions, width, height, ...options_ };
|
|
2755
|
+
options.width = Math.min(options.width, this.width - options.x);
|
|
2756
|
+
options.height = Math.min(options.height, this.height - options.y);
|
|
2757
|
+
return options;
|
|
2758
|
+
}
|
|
2759
|
+
_normalizeTextureWriteOptions(options_) {
|
|
2760
|
+
const { width, height } = this;
|
|
2761
|
+
const options = { ..._Texture.defaultTextureReadOptions, width, height, ...options_ };
|
|
2762
|
+
options.width = Math.min(options.width, this.width - options.x);
|
|
2763
|
+
options.height = Math.min(options.height, this.height - options.y);
|
|
2764
|
+
return options;
|
|
2765
|
+
}
|
|
2461
2766
|
};
|
|
2462
2767
|
var Texture = _Texture;
|
|
2463
2768
|
/** The texture can be bound for use as a sampled texture in a shader */
|
|
@@ -2474,13 +2779,12 @@ or create a device with the 'debug: true' prop.`;
|
|
|
2474
2779
|
__publicField(Texture, "TEXTURE", 4);
|
|
2475
2780
|
/** @deprecated Use Texture.RENDER */
|
|
2476
2781
|
__publicField(Texture, "RENDER_ATTACHMENT", 16);
|
|
2477
|
-
/** Default options */
|
|
2478
2782
|
__publicField(Texture, "defaultProps", {
|
|
2479
2783
|
...Resource.defaultProps,
|
|
2480
2784
|
data: null,
|
|
2481
2785
|
dimension: "2d",
|
|
2482
2786
|
format: "rgba8unorm",
|
|
2483
|
-
usage: _Texture.
|
|
2787
|
+
usage: _Texture.SAMPLE | _Texture.RENDER | _Texture.COPY_DST,
|
|
2484
2788
|
width: void 0,
|
|
2485
2789
|
height: void 0,
|
|
2486
2790
|
depth: 1,
|
|
@@ -2517,6 +2821,16 @@ or create a device with the 'debug: true' prop.`;
|
|
|
2517
2821
|
premultipliedAlpha: false,
|
|
2518
2822
|
flipY: false
|
|
2519
2823
|
});
|
|
2824
|
+
__publicField(Texture, "defaultTextureReadOptions", {
|
|
2825
|
+
x: 0,
|
|
2826
|
+
y: 0,
|
|
2827
|
+
z: 0,
|
|
2828
|
+
width: void 0,
|
|
2829
|
+
height: void 0,
|
|
2830
|
+
depthOrArrayLayers: 1,
|
|
2831
|
+
mipLevel: 0,
|
|
2832
|
+
aspect: "all"
|
|
2833
|
+
});
|
|
2520
2834
|
|
|
2521
2835
|
// ../core/src/adapter/resources/texture-view.ts
|
|
2522
2836
|
var _TextureView = class extends Resource {
|
|
@@ -2563,24 +2877,32 @@ or create a device with the 'debug: true' prop.`;
|
|
|
2563
2877
|
const log2 = shaderLog.slice().sort((a, b) => a.lineNum - b.lineNum);
|
|
2564
2878
|
switch (options?.showSourceCode || "no") {
|
|
2565
2879
|
case "all":
|
|
2566
|
-
let
|
|
2880
|
+
let currentMessageIndex = 0;
|
|
2567
2881
|
for (let lineNum = 1; lineNum <= lines.length; lineNum++) {
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
formattedLog +=
|
|
2882
|
+
const line = lines[lineNum - 1];
|
|
2883
|
+
const currentMessage = log2[currentMessageIndex];
|
|
2884
|
+
if (line && currentMessage) {
|
|
2885
|
+
formattedLog += getNumberedLine(line, lineNum, options);
|
|
2886
|
+
}
|
|
2887
|
+
while (log2.length > currentMessageIndex && currentMessage.lineNum === lineNum) {
|
|
2888
|
+
const message = log2[currentMessageIndex++];
|
|
2889
|
+
if (message) {
|
|
2890
|
+
formattedLog += formatCompilerMessage(message, lines, message.lineNum, {
|
|
2891
|
+
...options,
|
|
2892
|
+
inlineSource: false
|
|
2893
|
+
});
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2896
|
+
}
|
|
2897
|
+
while (log2.length > currentMessageIndex) {
|
|
2898
|
+
const message = log2[currentMessageIndex++];
|
|
2899
|
+
if (message) {
|
|
2900
|
+
formattedLog += formatCompilerMessage(message, [], 0, {
|
|
2572
2901
|
...options,
|
|
2573
2902
|
inlineSource: false
|
|
2574
2903
|
});
|
|
2575
2904
|
}
|
|
2576
2905
|
}
|
|
2577
|
-
while (log2.length > currentMessage) {
|
|
2578
|
-
const message = log2[currentMessage++];
|
|
2579
|
-
formattedLog += formatCompilerMessage(message, [], 0, {
|
|
2580
|
-
...options,
|
|
2581
|
-
inlineSource: false
|
|
2582
|
-
});
|
|
2583
|
-
}
|
|
2584
2906
|
return formattedLog;
|
|
2585
2907
|
case "issues":
|
|
2586
2908
|
case "no":
|
|
@@ -2602,8 +2924,8 @@ ${numberedLines}${positionIndicator}${message.type.toUpperCase()}: ${message.mes
|
|
|
2602
2924
|
|
|
2603
2925
|
`;
|
|
2604
2926
|
}
|
|
2605
|
-
const color = message.type === "error" ? "red" : "
|
|
2606
|
-
return options?.html ? `<div class='luma-compiler-log
|
|
2927
|
+
const color = message.type === "error" ? "red" : "orange";
|
|
2928
|
+
return options?.html ? `<div class='luma-compiler-log-${message.type}' style="color:${color};"><b> ${message.type.toUpperCase()}: ${message.message}</b></div>` : `${message.type.toUpperCase()}: ${message.message}`;
|
|
2607
2929
|
}
|
|
2608
2930
|
function getNumberedLines(lines, lineNum, options) {
|
|
2609
2931
|
let numberedLines = "";
|
|
@@ -2689,29 +3011,34 @@ ${numberedLines}${positionIndicator}${message.type.toUpperCase()}: ${message.mes
|
|
|
2689
3011
|
}
|
|
2690
3012
|
const shaderName = shaderId;
|
|
2691
3013
|
const shaderTitle = `${this.stage} shader "${shaderName}"`;
|
|
2692
|
-
|
|
3014
|
+
const htmlLog = formatCompilerLog(messages, this.source, { showSourceCode: "all", html: true });
|
|
2693
3015
|
const translatedSource = this.getTranslatedSource();
|
|
3016
|
+
const container = document.createElement("div");
|
|
3017
|
+
container.innerHTML = `<h1>Compilation error in ${shaderTitle}</h1>
|
|
3018
|
+
<div style="display:flex;position:fixed;top:10px;right:20px;gap:2px;">
|
|
3019
|
+
<button id="copy">Copy source</button><br/>
|
|
3020
|
+
<button id="close">Close</button>
|
|
3021
|
+
</div>
|
|
3022
|
+
<code><pre>${htmlLog}</pre></code>`;
|
|
2694
3023
|
if (translatedSource) {
|
|
2695
|
-
|
|
2696
|
-
}
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
button.
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
const dataURI = `data:text/plain,${encodeURIComponent(this.source)}`;
|
|
2714
|
-
navigator.clipboard.writeText(dataURI);
|
|
3024
|
+
container.innerHTML += `<br /><h1>Translated Source</h1><br /><br /><code><pre>${translatedSource}</pre></code>`;
|
|
3025
|
+
}
|
|
3026
|
+
container.style.top = "0";
|
|
3027
|
+
container.style.left = "0";
|
|
3028
|
+
container.style.background = "white";
|
|
3029
|
+
container.style.position = "fixed";
|
|
3030
|
+
container.style.zIndex = "9999";
|
|
3031
|
+
container.style.maxWidth = "100vw";
|
|
3032
|
+
container.style.maxHeight = "100vh";
|
|
3033
|
+
container.style.overflowY = "auto";
|
|
3034
|
+
document.body.appendChild(container);
|
|
3035
|
+
const error = container.querySelector(".luma-compiler-log-error");
|
|
3036
|
+
error?.scrollIntoView();
|
|
3037
|
+
container.querySelector("button#close").onclick = () => {
|
|
3038
|
+
container.remove();
|
|
3039
|
+
};
|
|
3040
|
+
container.querySelector("button#copy").onclick = () => {
|
|
3041
|
+
navigator.clipboard.writeText(this.source);
|
|
2715
3042
|
};
|
|
2716
3043
|
}
|
|
2717
3044
|
};
|
|
@@ -2731,7 +3058,7 @@ ${htmlLog}
|
|
|
2731
3058
|
function getShaderName(shader, defaultName = "unnamed") {
|
|
2732
3059
|
const SHADER_NAME_REGEXP = /#define[\s*]SHADER_NAME[\s*]([A-Za-z0-9_-]+)[\s*]/;
|
|
2733
3060
|
const match = SHADER_NAME_REGEXP.exec(shader);
|
|
2734
|
-
return match
|
|
3061
|
+
return match?.[1] ?? defaultName;
|
|
2735
3062
|
}
|
|
2736
3063
|
|
|
2737
3064
|
// ../core/src/adapter/resources/framebuffer.ts
|
|
@@ -2757,7 +3084,12 @@ ${htmlLog}
|
|
|
2757
3084
|
(colorAttachment) => colorAttachment.texture.clone(size)
|
|
2758
3085
|
);
|
|
2759
3086
|
const depthStencilAttachment = this.depthStencilAttachment && this.depthStencilAttachment.texture.clone(size);
|
|
2760
|
-
return this.device.createFramebuffer({
|
|
3087
|
+
return this.device.createFramebuffer({
|
|
3088
|
+
...this.props,
|
|
3089
|
+
...size,
|
|
3090
|
+
colorAttachments,
|
|
3091
|
+
depthStencilAttachment
|
|
3092
|
+
});
|
|
2761
3093
|
}
|
|
2762
3094
|
resize(size) {
|
|
2763
3095
|
let updateSize = !size;
|
|
@@ -2832,17 +3164,15 @@ ${htmlLog}
|
|
|
2832
3164
|
* and destroys existing textures if owned
|
|
2833
3165
|
*/
|
|
2834
3166
|
resizeAttachments(width, height) {
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
}
|
|
2845
|
-
}
|
|
3167
|
+
this.colorAttachments.forEach((colorAttachment, i) => {
|
|
3168
|
+
const resizedTexture = colorAttachment.texture.clone({
|
|
3169
|
+
width,
|
|
3170
|
+
height
|
|
3171
|
+
});
|
|
3172
|
+
this.destroyAttachedResource(colorAttachment);
|
|
3173
|
+
this.colorAttachments[i] = resizedTexture.view;
|
|
3174
|
+
this.attachResource(resizedTexture.view);
|
|
3175
|
+
});
|
|
2846
3176
|
if (this.depthStencilAttachment) {
|
|
2847
3177
|
const resizedTexture = this.depthStencilAttachment.texture.clone({
|
|
2848
3178
|
width,
|
|
@@ -3353,6 +3683,18 @@ ${htmlLog}
|
|
|
3353
3683
|
count: void 0
|
|
3354
3684
|
});
|
|
3355
3685
|
|
|
3686
|
+
// ../core/src/adapter/resources/fence.ts
|
|
3687
|
+
var _Fence = class extends Resource {
|
|
3688
|
+
[Symbol.toStringTag] = "WEBGLFence";
|
|
3689
|
+
constructor(device, props = {}) {
|
|
3690
|
+
super(device, props, _Fence.defaultProps);
|
|
3691
|
+
}
|
|
3692
|
+
};
|
|
3693
|
+
var Fence = _Fence;
|
|
3694
|
+
__publicField(Fence, "defaultProps", {
|
|
3695
|
+
...Resource.defaultProps
|
|
3696
|
+
});
|
|
3697
|
+
|
|
3356
3698
|
// ../core/src/adapter/resources/pipeline-layout.ts
|
|
3357
3699
|
var _PipelineLayout = class extends Resource {
|
|
3358
3700
|
get [Symbol.toStringTag]() {
|
|
@@ -3384,17 +3726,6 @@ ${htmlLog}
|
|
|
3384
3726
|
return new Type(scratchArrayBuffer, 0, length);
|
|
3385
3727
|
}
|
|
3386
3728
|
|
|
3387
|
-
// ../core/src/utils/is-array.ts
|
|
3388
|
-
function isTypedArray(value) {
|
|
3389
|
-
return ArrayBuffer.isView(value) && !(value instanceof DataView);
|
|
3390
|
-
}
|
|
3391
|
-
function isNumberArray(value) {
|
|
3392
|
-
if (Array.isArray(value)) {
|
|
3393
|
-
return value.length === 0 || typeof value[0] === "number";
|
|
3394
|
-
}
|
|
3395
|
-
return isTypedArray(value);
|
|
3396
|
-
}
|
|
3397
|
-
|
|
3398
3729
|
// ../core/src/portable/uniform-buffer-layout.ts
|
|
3399
3730
|
var minBufferSize = 1024;
|
|
3400
3731
|
var UniformBufferLayout = class {
|
|
@@ -3405,67 +3736,114 @@ ${htmlLog}
|
|
|
3405
3736
|
constructor(uniformTypes, uniformSizes = {}) {
|
|
3406
3737
|
let size = 0;
|
|
3407
3738
|
for (const [key, uniformType] of Object.entries(uniformTypes)) {
|
|
3408
|
-
|
|
3409
|
-
const { type, components } = typeAndComponents;
|
|
3410
|
-
const count = components * (uniformSizes?.[key] ?? 1);
|
|
3411
|
-
size = alignTo(size, count);
|
|
3412
|
-
const offset = size;
|
|
3413
|
-
size += count;
|
|
3414
|
-
this.layout[key] = { type, size: count, offset };
|
|
3739
|
+
size = this._addToLayout(key, uniformType, size, uniformSizes?.[key]);
|
|
3415
3740
|
}
|
|
3416
3741
|
size += (4 - size % 4) % 4;
|
|
3417
|
-
|
|
3418
|
-
|
|
3742
|
+
this.byteLength = Math.max(size * 4, minBufferSize);
|
|
3743
|
+
}
|
|
3744
|
+
/** Does this layout have a field with specified name */
|
|
3745
|
+
has(name2) {
|
|
3746
|
+
return Boolean(this.layout[name2]);
|
|
3747
|
+
}
|
|
3748
|
+
/** Get offset and size for a field with specified name */
|
|
3749
|
+
get(name2) {
|
|
3750
|
+
const layout = this.layout[name2];
|
|
3751
|
+
return layout;
|
|
3419
3752
|
}
|
|
3420
3753
|
/** Get the data for the complete buffer */
|
|
3421
3754
|
getData(uniformValues) {
|
|
3422
|
-
const
|
|
3755
|
+
const buffer = getScratchArrayBuffer(this.byteLength);
|
|
3423
3756
|
const typedArrays = {
|
|
3424
|
-
i32: new Int32Array(
|
|
3425
|
-
u32: new Uint32Array(
|
|
3426
|
-
f32: new Float32Array(
|
|
3427
|
-
|
|
3428
|
-
f16: new Uint16Array(arrayBuffer2)
|
|
3757
|
+
i32: new Int32Array(buffer),
|
|
3758
|
+
u32: new Uint32Array(buffer),
|
|
3759
|
+
f32: new Float32Array(buffer),
|
|
3760
|
+
f16: new Uint16Array(buffer)
|
|
3429
3761
|
};
|
|
3430
3762
|
for (const [name2, value] of Object.entries(uniformValues)) {
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3763
|
+
this._writeCompositeValue(typedArrays, name2, value);
|
|
3764
|
+
}
|
|
3765
|
+
return new Uint8Array(buffer, 0, this.byteLength);
|
|
3766
|
+
}
|
|
3767
|
+
// Recursively add a uniform to the layout
|
|
3768
|
+
_addToLayout(name2, type, offset, count = 1) {
|
|
3769
|
+
if (typeof type === "string") {
|
|
3770
|
+
const info = getVariableShaderTypeInfo(type);
|
|
3771
|
+
const sizeInSlots = info.components * count;
|
|
3772
|
+
const alignedOffset = alignTo(offset, info.components);
|
|
3773
|
+
this.layout[name2] = {
|
|
3774
|
+
offset: alignedOffset,
|
|
3775
|
+
size: sizeInSlots,
|
|
3776
|
+
type: info.type
|
|
3777
|
+
};
|
|
3778
|
+
return alignedOffset + sizeInSlots;
|
|
3779
|
+
}
|
|
3780
|
+
if (Array.isArray(type)) {
|
|
3781
|
+
const elementType = type[0];
|
|
3782
|
+
const length = count > 1 ? count : type.length > 1 ? type[1] : 1;
|
|
3783
|
+
let arrayOffset = alignTo(offset, 4);
|
|
3784
|
+
for (let i = 0; i < length; i++) {
|
|
3785
|
+
arrayOffset = this._addToLayout(`${name2}[${i}]`, elementType, arrayOffset);
|
|
3435
3786
|
}
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
)();
|
|
3443
|
-
continue;
|
|
3444
|
-
}
|
|
3445
|
-
typedArray[offset] = Number(value);
|
|
3446
|
-
} else {
|
|
3447
|
-
if (!isNumberArray(value)) {
|
|
3448
|
-
log.warn(
|
|
3449
|
-
`Supplied value for multi component / array uniform ${name2} is not a numeric array: ${value}`
|
|
3450
|
-
)();
|
|
3451
|
-
continue;
|
|
3452
|
-
}
|
|
3453
|
-
typedArray.set(value, offset);
|
|
3787
|
+
return arrayOffset;
|
|
3788
|
+
}
|
|
3789
|
+
if (typeof type === "object") {
|
|
3790
|
+
let structOffset = alignTo(offset, 4);
|
|
3791
|
+
for (const [memberName, memberType] of Object.entries(type)) {
|
|
3792
|
+
structOffset = this._addToLayout(`${name2}.${memberName}`, memberType, structOffset);
|
|
3454
3793
|
}
|
|
3794
|
+
return structOffset;
|
|
3455
3795
|
}
|
|
3456
|
-
|
|
3796
|
+
throw new Error(`Unsupported CompositeShaderType for ${name2}`);
|
|
3457
3797
|
}
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3798
|
+
_writeCompositeValue(typedArrays, baseName, value) {
|
|
3799
|
+
if (this.layout[baseName]) {
|
|
3800
|
+
this._writeToBuffer(typedArrays, baseName, value);
|
|
3801
|
+
return;
|
|
3802
|
+
}
|
|
3803
|
+
if (Array.isArray(value)) {
|
|
3804
|
+
for (let i = 0; i < value.length; i++) {
|
|
3805
|
+
const element = value[i];
|
|
3806
|
+
const indexedName = `${baseName}[${i}]`;
|
|
3807
|
+
this._writeCompositeValue(typedArrays, indexedName, element);
|
|
3808
|
+
}
|
|
3809
|
+
return;
|
|
3810
|
+
}
|
|
3811
|
+
if (typeof value === "object" && value !== null) {
|
|
3812
|
+
for (const [key, subValue] of Object.entries(value)) {
|
|
3813
|
+
const nestedName = `${baseName}.${key}`;
|
|
3814
|
+
this._writeCompositeValue(typedArrays, nestedName, subValue);
|
|
3815
|
+
}
|
|
3816
|
+
return;
|
|
3817
|
+
}
|
|
3818
|
+
log.warn(`Unsupported uniform value for ${baseName}:`, value)();
|
|
3461
3819
|
}
|
|
3462
|
-
|
|
3463
|
-
get(name2) {
|
|
3820
|
+
_writeToBuffer(typedArrays, name2, value) {
|
|
3464
3821
|
const layout = this.layout[name2];
|
|
3465
|
-
|
|
3822
|
+
if (!layout) {
|
|
3823
|
+
log.warn(`Uniform ${name2} not found in layout`)();
|
|
3824
|
+
return;
|
|
3825
|
+
}
|
|
3826
|
+
const { type, size, offset } = layout;
|
|
3827
|
+
const array = typedArrays[type];
|
|
3828
|
+
if (size === 1) {
|
|
3829
|
+
array[offset] = Number(value);
|
|
3830
|
+
} else {
|
|
3831
|
+
array.set(value, offset);
|
|
3832
|
+
}
|
|
3466
3833
|
}
|
|
3467
3834
|
};
|
|
3468
3835
|
|
|
3836
|
+
// ../core/src/utils/is-array.ts
|
|
3837
|
+
function isTypedArray(value) {
|
|
3838
|
+
return ArrayBuffer.isView(value) && !(value instanceof DataView);
|
|
3839
|
+
}
|
|
3840
|
+
function isNumberArray(value) {
|
|
3841
|
+
if (Array.isArray(value)) {
|
|
3842
|
+
return value.length === 0 || typeof value[0] === "number";
|
|
3843
|
+
}
|
|
3844
|
+
return isTypedArray(value);
|
|
3845
|
+
}
|
|
3846
|
+
|
|
3469
3847
|
// ../core/src/utils/array-equal.ts
|
|
3470
3848
|
function arrayEqual(a, b, limit = 16) {
|
|
3471
3849
|
if (a !== b) {
|
|
@@ -3657,6 +4035,44 @@ ${htmlLog}
|
|
|
3657
4035
|
}
|
|
3658
4036
|
};
|
|
3659
4037
|
|
|
4038
|
+
// ../core/src/shadertypes/textures/texture-layout.ts
|
|
4039
|
+
function getTextureImageView(arrayBuffer2, memoryLayout, format, image = 0) {
|
|
4040
|
+
const formatInfo = textureFormatDecoder.getInfo(format);
|
|
4041
|
+
const bytesPerComponent = formatInfo.bytesPerPixel / formatInfo.components;
|
|
4042
|
+
const { bytesPerImage } = memoryLayout;
|
|
4043
|
+
const offset = bytesPerImage * image;
|
|
4044
|
+
const totalPixels = memoryLayout.bytesPerImage / bytesPerComponent;
|
|
4045
|
+
switch (format) {
|
|
4046
|
+
case "rgba8unorm":
|
|
4047
|
+
case "bgra8unorm":
|
|
4048
|
+
case "rgba8uint":
|
|
4049
|
+
return new Uint8Array(arrayBuffer2, offset, totalPixels);
|
|
4050
|
+
case "r8unorm":
|
|
4051
|
+
return new Uint8Array(arrayBuffer2, offset, totalPixels);
|
|
4052
|
+
case "r16uint":
|
|
4053
|
+
case "rgba16uint":
|
|
4054
|
+
return new Uint16Array(arrayBuffer2, offset, totalPixels);
|
|
4055
|
+
case "r32uint":
|
|
4056
|
+
case "rgba32uint":
|
|
4057
|
+
return new Uint32Array(arrayBuffer2, offset, totalPixels);
|
|
4058
|
+
case "r32float":
|
|
4059
|
+
return new Float32Array(arrayBuffer2, offset, totalPixels);
|
|
4060
|
+
case "rgba16float":
|
|
4061
|
+
return new Uint16Array(arrayBuffer2, offset, totalPixels);
|
|
4062
|
+
case "rgba32float":
|
|
4063
|
+
return new Float32Array(arrayBuffer2, offset, totalPixels);
|
|
4064
|
+
default:
|
|
4065
|
+
throw new Error(`Unsupported format: ${format}`);
|
|
4066
|
+
}
|
|
4067
|
+
}
|
|
4068
|
+
function setTextureImageData(arrayBuffer2, memoryLayout, format, data, image = 0) {
|
|
4069
|
+
const offset = 0;
|
|
4070
|
+
const totalPixels = memoryLayout.bytesPerImage / memoryLayout.bytesPerPixel;
|
|
4071
|
+
const subArray = data.subarray(0, totalPixels);
|
|
4072
|
+
const typedArray = getTextureImageView(arrayBuffer2, memoryLayout, format, image);
|
|
4073
|
+
typedArray.set(subArray, offset);
|
|
4074
|
+
}
|
|
4075
|
+
|
|
3660
4076
|
// ../core/src/shadertypes/textures/pixel-utils.ts
|
|
3661
4077
|
function readPixel(pixelData, x, y, bitsPerChannel) {
|
|
3662
4078
|
if (x < 0 || x >= pixelData.width || y < 0 || y >= pixelData.height) {
|
|
@@ -3667,7 +4083,7 @@ ${htmlLog}
|
|
|
3667
4083
|
let bitOffsetWithinPixel = 0;
|
|
3668
4084
|
const channels = [];
|
|
3669
4085
|
for (let i = 0; i < 4; i++) {
|
|
3670
|
-
const bits = bitsPerChannel[i];
|
|
4086
|
+
const bits = bitsPerChannel[i] ?? 0;
|
|
3671
4087
|
if (bits <= 0) {
|
|
3672
4088
|
channels.push(0);
|
|
3673
4089
|
} else {
|
|
@@ -3676,14 +4092,14 @@ ${htmlLog}
|
|
|
3676
4092
|
bitOffsetWithinPixel += bits;
|
|
3677
4093
|
}
|
|
3678
4094
|
}
|
|
3679
|
-
return [channels[0], channels[1], channels[2], channels[3]];
|
|
4095
|
+
return [channels[0] ?? 0, channels[1] ?? 0, channels[2] ?? 0, channels[3] ?? 0];
|
|
3680
4096
|
}
|
|
3681
4097
|
function writePixel(dataView, bitOffset, bitsPerChannel, pixel) {
|
|
3682
4098
|
let currentBitOffset = bitOffset;
|
|
3683
4099
|
for (let channel = 0; channel < 4; channel++) {
|
|
3684
|
-
const bits = bitsPerChannel[channel];
|
|
4100
|
+
const bits = bitsPerChannel[channel] ?? 0;
|
|
3685
4101
|
const maxValue = (1 << bits) - 1;
|
|
3686
|
-
const channelValue = pixel[channel] & maxValue;
|
|
4102
|
+
const channelValue = (pixel[channel] ?? 0) & maxValue;
|
|
3687
4103
|
writeBitsToDataView(dataView, currentBitOffset, bits, channelValue);
|
|
3688
4104
|
currentBitOffset += bits;
|
|
3689
4105
|
}
|