@luma.gl/core 9.3.0-alpha.2 → 9.3.0-alpha.6
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/adapter/canvas-context.d.ts +6 -181
- package/dist/adapter/canvas-context.d.ts.map +1 -1
- package/dist/adapter/canvas-context.js +5 -450
- package/dist/adapter/canvas-context.js.map +1 -1
- package/dist/adapter/canvas-observer.d.ts +32 -0
- package/dist/adapter/canvas-observer.d.ts.map +1 -0
- package/dist/adapter/canvas-observer.js +90 -0
- package/dist/adapter/canvas-observer.js.map +1 -0
- package/dist/adapter/canvas-surface.d.ts +150 -0
- package/dist/adapter/canvas-surface.d.ts.map +1 -0
- package/dist/adapter/canvas-surface.js +392 -0
- package/dist/adapter/canvas-surface.js.map +1 -0
- package/dist/adapter/device.d.ts +64 -9
- package/dist/adapter/device.d.ts.map +1 -1
- package/dist/adapter/device.js +108 -4
- package/dist/adapter/device.js.map +1 -1
- package/dist/adapter/luma.js +1 -1
- package/dist/adapter/presentation-context.d.ts +11 -0
- package/dist/adapter/presentation-context.d.ts.map +1 -0
- package/dist/adapter/presentation-context.js +12 -0
- package/dist/adapter/presentation-context.js.map +1 -0
- package/dist/adapter/resources/buffer.d.ts +1 -1
- package/dist/adapter/resources/buffer.d.ts.map +1 -1
- package/dist/adapter/resources/buffer.js +14 -6
- package/dist/adapter/resources/buffer.js.map +1 -1
- package/dist/adapter/resources/command-encoder.d.ts +27 -6
- package/dist/adapter/resources/command-encoder.d.ts.map +1 -1
- package/dist/adapter/resources/command-encoder.js +65 -1
- package/dist/adapter/resources/command-encoder.js.map +1 -1
- package/dist/adapter/resources/fence.d.ts +1 -1
- package/dist/adapter/resources/fence.d.ts.map +1 -1
- package/dist/adapter/resources/fence.js +3 -1
- package/dist/adapter/resources/fence.js.map +1 -1
- package/dist/adapter/resources/framebuffer.d.ts.map +1 -1
- package/dist/adapter/resources/framebuffer.js +9 -11
- package/dist/adapter/resources/framebuffer.js.map +1 -1
- package/dist/adapter/resources/query-set.d.ts +17 -1
- package/dist/adapter/resources/query-set.d.ts.map +1 -1
- package/dist/adapter/resources/query-set.js.map +1 -1
- package/dist/adapter/resources/render-pipeline.d.ts +19 -7
- package/dist/adapter/resources/render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/render-pipeline.js +20 -2
- package/dist/adapter/resources/render-pipeline.js.map +1 -1
- package/dist/adapter/resources/resource.d.ts +8 -0
- package/dist/adapter/resources/resource.d.ts.map +1 -1
- package/dist/adapter/resources/resource.js +240 -14
- package/dist/adapter/resources/resource.js.map +1 -1
- package/dist/adapter/resources/shader.js +27 -25
- package/dist/adapter/resources/shader.js.map +1 -1
- package/dist/adapter/resources/shared-render-pipeline.d.ts +22 -0
- package/dist/adapter/resources/shared-render-pipeline.d.ts.map +1 -0
- package/dist/adapter/resources/shared-render-pipeline.js +25 -0
- package/dist/adapter/resources/shared-render-pipeline.js.map +1 -0
- package/dist/adapter/resources/texture.d.ts +78 -12
- package/dist/adapter/resources/texture.d.ts.map +1 -1
- package/dist/adapter/resources/texture.js +182 -30
- package/dist/adapter/resources/texture.js.map +1 -1
- package/dist/adapter-utils/format-compiler-log.d.ts.map +1 -1
- package/dist/adapter-utils/format-compiler-log.js +23 -15
- package/dist/adapter-utils/format-compiler-log.js.map +1 -1
- package/dist/dist.dev.js +1265 -362
- package/dist/dist.min.js +10 -9
- package/dist/index.cjs +1027 -243
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/shadertypes/data-types/decode-shader-types.d.ts +2 -2
- package/dist/shadertypes/data-types/decode-shader-types.d.ts.map +1 -1
- package/dist/shadertypes/data-types/decode-shader-types.js +11 -2
- package/dist/shadertypes/data-types/decode-shader-types.js.map +1 -1
- package/dist/shadertypes/textures/pixel-utils.js +4 -4
- package/dist/shadertypes/textures/pixel-utils.js.map +1 -1
- package/dist/shadertypes/textures/texture-format-decoder.d.ts.map +1 -1
- package/dist/shadertypes/textures/texture-format-decoder.js +53 -8
- package/dist/shadertypes/textures/texture-format-decoder.js.map +1 -1
- package/dist/shadertypes/textures/texture-format-table.d.ts.map +1 -1
- package/dist/shadertypes/textures/texture-format-table.js +10 -9
- package/dist/shadertypes/textures/texture-format-table.js.map +1 -1
- package/dist/shadertypes/textures/texture-formats.d.ts +5 -2
- package/dist/shadertypes/textures/texture-formats.d.ts.map +1 -1
- package/dist/shadertypes/textures/texture-formats.js.map +1 -1
- package/dist/shadertypes/textures/texture-layout.d.ts +1 -1
- package/dist/utils/array-equal.d.ts +1 -1
- package/dist/utils/array-equal.d.ts.map +1 -1
- package/dist/utils/array-equal.js +15 -9
- package/dist/utils/array-equal.js.map +1 -1
- package/dist/utils/assert.d.ts +5 -0
- package/dist/utils/assert.d.ts.map +1 -0
- package/dist/utils/assert.js +17 -0
- package/dist/utils/assert.js.map +1 -0
- package/dist/utils/stats-manager.d.ts.map +1 -1
- package/dist/utils/stats-manager.js +61 -1
- package/dist/utils/stats-manager.js.map +1 -1
- package/package.json +6 -6
- package/src/adapter/canvas-context.ts +7 -590
- package/src/adapter/canvas-observer.ts +130 -0
- package/src/adapter/canvas-surface.ts +521 -0
- package/src/adapter/device.ts +174 -13
- package/src/adapter/presentation-context.ts +16 -0
- package/src/adapter/resources/buffer.ts +13 -5
- package/src/adapter/resources/command-encoder.ts +96 -7
- package/src/adapter/resources/fence.ts +3 -1
- package/src/adapter/resources/framebuffer.ts +9 -11
- package/src/adapter/resources/query-set.ts +17 -1
- package/src/adapter/resources/render-pipeline.ts +42 -13
- package/src/adapter/resources/resource.ts +284 -14
- package/src/adapter/resources/shader.ts +28 -28
- package/src/adapter/resources/shared-render-pipeline.ts +40 -0
- package/src/adapter/resources/texture.ts +269 -40
- package/src/adapter-utils/format-compiler-log.ts +23 -15
- package/src/index.ts +8 -0
- package/src/shadertypes/data-types/decode-shader-types.ts +13 -4
- package/src/shadertypes/textures/pixel-utils.ts +4 -4
- package/src/shadertypes/textures/texture-format-decoder.ts +73 -8
- package/src/shadertypes/textures/texture-format-table.ts +10 -9
- package/src/shadertypes/textures/texture-formats.ts +6 -1
- package/src/utils/array-equal.ts +21 -9
- package/src/utils/assert.ts +18 -0
- package/src/utils/stats-manager.ts +76 -2
package/dist/index.cjs
CHANGED
|
@@ -39,12 +39,14 @@ __export(dist_exports, {
|
|
|
39
39
|
Fence: () => Fence,
|
|
40
40
|
Framebuffer: () => Framebuffer,
|
|
41
41
|
PipelineLayout: () => PipelineLayout,
|
|
42
|
+
PresentationContext: () => PresentationContext,
|
|
42
43
|
QuerySet: () => QuerySet,
|
|
43
44
|
RenderPass: () => RenderPass,
|
|
44
45
|
RenderPipeline: () => RenderPipeline,
|
|
45
46
|
Resource: () => Resource,
|
|
46
47
|
Sampler: () => Sampler,
|
|
47
48
|
Shader: () => Shader,
|
|
49
|
+
SharedRenderPipeline: () => SharedRenderPipeline,
|
|
48
50
|
Texture: () => Texture,
|
|
49
51
|
TextureFormatDecoder: () => TextureFormatDecoder,
|
|
50
52
|
TextureView: () => TextureView,
|
|
@@ -55,6 +57,8 @@ __export(dist_exports, {
|
|
|
55
57
|
VertexArray: () => VertexArray,
|
|
56
58
|
_getTextureFormatDefinition: () => getTextureFormatDefinition,
|
|
57
59
|
_getTextureFormatTable: () => getTextureFormatTable,
|
|
60
|
+
assert: () => assert,
|
|
61
|
+
assertDefined: () => assertDefined,
|
|
58
62
|
getAttributeInfosFromLayouts: () => getAttributeInfosFromLayouts,
|
|
59
63
|
getAttributeShaderTypeInfo: () => getAttributeShaderTypeInfo,
|
|
60
64
|
getDataType: () => getDataType,
|
|
@@ -80,6 +84,24 @@ module.exports = __toCommonJS(dist_exports);
|
|
|
80
84
|
|
|
81
85
|
// dist/utils/stats-manager.js
|
|
82
86
|
var import_stats = require("@probe.gl/stats");
|
|
87
|
+
var GPU_TIME_AND_MEMORY_STATS = "GPU Time and Memory";
|
|
88
|
+
var GPU_TIME_AND_MEMORY_STAT_ORDER = [
|
|
89
|
+
"Adapter",
|
|
90
|
+
"GPU",
|
|
91
|
+
"GPU Type",
|
|
92
|
+
"GPU Backend",
|
|
93
|
+
"Frame Rate",
|
|
94
|
+
"CPU Time",
|
|
95
|
+
"GPU Time",
|
|
96
|
+
"GPU Memory",
|
|
97
|
+
"Buffer Memory",
|
|
98
|
+
"Texture Memory",
|
|
99
|
+
"Referenced Buffer Memory",
|
|
100
|
+
"Referenced Texture Memory",
|
|
101
|
+
"Swap Chain Texture"
|
|
102
|
+
];
|
|
103
|
+
var ORDERED_STATS_CACHE = /* @__PURE__ */ new WeakMap();
|
|
104
|
+
var ORDERED_STAT_NAME_SET_CACHE = /* @__PURE__ */ new WeakMap();
|
|
83
105
|
var StatsManager = class {
|
|
84
106
|
stats = /* @__PURE__ */ new Map();
|
|
85
107
|
getStats(name2) {
|
|
@@ -89,10 +111,50 @@ var StatsManager = class {
|
|
|
89
111
|
if (!this.stats.has(name2)) {
|
|
90
112
|
this.stats.set(name2, new import_stats.Stats({ id: name2 }));
|
|
91
113
|
}
|
|
92
|
-
|
|
114
|
+
const stats = this.stats.get(name2);
|
|
115
|
+
if (name2 === GPU_TIME_AND_MEMORY_STATS) {
|
|
116
|
+
initializeStats(stats, GPU_TIME_AND_MEMORY_STAT_ORDER);
|
|
117
|
+
}
|
|
118
|
+
return stats;
|
|
93
119
|
}
|
|
94
120
|
};
|
|
95
121
|
var lumaStats = new StatsManager();
|
|
122
|
+
function initializeStats(stats, orderedStatNames) {
|
|
123
|
+
const statsMap = stats.stats;
|
|
124
|
+
let addedOrderedStat = false;
|
|
125
|
+
for (const statName of orderedStatNames) {
|
|
126
|
+
if (!statsMap[statName]) {
|
|
127
|
+
stats.get(statName);
|
|
128
|
+
addedOrderedStat = true;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const statCount = Object.keys(statsMap).length;
|
|
132
|
+
const cachedStats = ORDERED_STATS_CACHE.get(stats);
|
|
133
|
+
if (!addedOrderedStat && (cachedStats == null ? void 0 : cachedStats.orderedStatNames) === orderedStatNames && cachedStats.statCount === statCount) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const reorderedStats = {};
|
|
137
|
+
let orderedStatNamesSet = ORDERED_STAT_NAME_SET_CACHE.get(orderedStatNames);
|
|
138
|
+
if (!orderedStatNamesSet) {
|
|
139
|
+
orderedStatNamesSet = new Set(orderedStatNames);
|
|
140
|
+
ORDERED_STAT_NAME_SET_CACHE.set(orderedStatNames, orderedStatNamesSet);
|
|
141
|
+
}
|
|
142
|
+
for (const statName of orderedStatNames) {
|
|
143
|
+
if (statsMap[statName]) {
|
|
144
|
+
reorderedStats[statName] = statsMap[statName];
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
for (const [statName, stat] of Object.entries(statsMap)) {
|
|
148
|
+
if (!orderedStatNamesSet.has(statName)) {
|
|
149
|
+
reorderedStats[statName] = stat;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
for (const statName of Object.keys(statsMap)) {
|
|
153
|
+
delete statsMap[statName];
|
|
154
|
+
}
|
|
155
|
+
Object.assign(statsMap, reorderedStats);
|
|
156
|
+
ORDERED_STATS_CACHE.set(stats, { orderedStatNames, statCount });
|
|
157
|
+
}
|
|
96
158
|
|
|
97
159
|
// dist/utils/log.js
|
|
98
160
|
var import_log = require("@probe.gl/log");
|
|
@@ -107,6 +169,57 @@ function uid(id = "id") {
|
|
|
107
169
|
}
|
|
108
170
|
|
|
109
171
|
// dist/adapter/resources/resource.js
|
|
172
|
+
var CPU_HOTSPOT_PROFILER_MODULE = "cpu-hotspot-profiler";
|
|
173
|
+
var RESOURCE_COUNTS_STATS = "GPU Resource Counts";
|
|
174
|
+
var LEGACY_RESOURCE_COUNTS_STATS = "Resource Counts";
|
|
175
|
+
var GPU_TIME_AND_MEMORY_STATS2 = "GPU Time and Memory";
|
|
176
|
+
var BASE_RESOURCE_COUNT_ORDER = [
|
|
177
|
+
"Resources",
|
|
178
|
+
"Buffers",
|
|
179
|
+
"Textures",
|
|
180
|
+
"Samplers",
|
|
181
|
+
"TextureViews",
|
|
182
|
+
"Framebuffers",
|
|
183
|
+
"QuerySets",
|
|
184
|
+
"Shaders",
|
|
185
|
+
"RenderPipelines",
|
|
186
|
+
"ComputePipelines",
|
|
187
|
+
"PipelineLayouts",
|
|
188
|
+
"VertexArrays",
|
|
189
|
+
"RenderPasss",
|
|
190
|
+
"ComputePasss",
|
|
191
|
+
"CommandEncoders",
|
|
192
|
+
"CommandBuffers"
|
|
193
|
+
];
|
|
194
|
+
var WEBGL_RESOURCE_COUNT_ORDER = [
|
|
195
|
+
"Resources",
|
|
196
|
+
"Buffers",
|
|
197
|
+
"Textures",
|
|
198
|
+
"Samplers",
|
|
199
|
+
"TextureViews",
|
|
200
|
+
"Framebuffers",
|
|
201
|
+
"QuerySets",
|
|
202
|
+
"Shaders",
|
|
203
|
+
"RenderPipelines",
|
|
204
|
+
"SharedRenderPipelines",
|
|
205
|
+
"ComputePipelines",
|
|
206
|
+
"PipelineLayouts",
|
|
207
|
+
"VertexArrays",
|
|
208
|
+
"RenderPasss",
|
|
209
|
+
"ComputePasss",
|
|
210
|
+
"CommandEncoders",
|
|
211
|
+
"CommandBuffers"
|
|
212
|
+
];
|
|
213
|
+
var BASE_RESOURCE_COUNT_STAT_ORDER = BASE_RESOURCE_COUNT_ORDER.flatMap((resourceType) => [
|
|
214
|
+
`${resourceType} Created`,
|
|
215
|
+
`${resourceType} Active`
|
|
216
|
+
]);
|
|
217
|
+
var WEBGL_RESOURCE_COUNT_STAT_ORDER = WEBGL_RESOURCE_COUNT_ORDER.flatMap((resourceType) => [
|
|
218
|
+
`${resourceType} Created`,
|
|
219
|
+
`${resourceType} Active`
|
|
220
|
+
]);
|
|
221
|
+
var ORDERED_STATS_CACHE2 = /* @__PURE__ */ new WeakMap();
|
|
222
|
+
var ORDERED_STAT_NAME_SET_CACHE2 = /* @__PURE__ */ new WeakMap();
|
|
110
223
|
var Resource = class {
|
|
111
224
|
toString() {
|
|
112
225
|
return `${this[Symbol.toStringTag] || this.constructor.name}:"${this.id}"`;
|
|
@@ -123,6 +236,8 @@ var Resource = class {
|
|
|
123
236
|
destroyed = false;
|
|
124
237
|
/** For resources that allocate GPU memory */
|
|
125
238
|
allocatedBytes = 0;
|
|
239
|
+
/** Stats bucket currently holding the tracked allocation */
|
|
240
|
+
allocatedBytesName = null;
|
|
126
241
|
/** Attached resources will be destroyed when this resource is destroyed. Tracks auto-created "sub" resources. */
|
|
127
242
|
_attachedResources = /* @__PURE__ */ new Set();
|
|
128
243
|
/**
|
|
@@ -144,6 +259,9 @@ var Resource = class {
|
|
|
144
259
|
* destroy can be called on any resource to release it before it is garbage collected.
|
|
145
260
|
*/
|
|
146
261
|
destroy() {
|
|
262
|
+
if (this.destroyed) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
147
265
|
this.destroyResource();
|
|
148
266
|
}
|
|
149
267
|
/** @deprecated Use destroy() */
|
|
@@ -182,7 +300,7 @@ var Resource = class {
|
|
|
182
300
|
}
|
|
183
301
|
/** Destroy all owned resources. Make sure the resources are no longer needed before calling. */
|
|
184
302
|
destroyAttachedResources() {
|
|
185
|
-
for (const resource of
|
|
303
|
+
for (const resource of this._attachedResources) {
|
|
186
304
|
resource.destroy();
|
|
187
305
|
}
|
|
188
306
|
this._attachedResources = /* @__PURE__ */ new Set();
|
|
@@ -190,37 +308,107 @@ var Resource = class {
|
|
|
190
308
|
// PROTECTED METHODS
|
|
191
309
|
/** Perform all destroy steps. Can be called by derived resources when overriding destroy() */
|
|
192
310
|
destroyResource() {
|
|
311
|
+
if (this.destroyed) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
193
314
|
this.destroyAttachedResources();
|
|
194
315
|
this.removeStats();
|
|
195
316
|
this.destroyed = true;
|
|
196
317
|
}
|
|
197
318
|
/** Called by .destroy() to track object destruction. Subclass must call if overriding destroy() */
|
|
198
319
|
removeStats() {
|
|
199
|
-
const
|
|
200
|
-
const
|
|
201
|
-
|
|
320
|
+
const profiler = getCpuHotspotProfiler(this._device);
|
|
321
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
322
|
+
const statsObjects = [
|
|
323
|
+
this._device.statsManager.getStats(RESOURCE_COUNTS_STATS),
|
|
324
|
+
this._device.statsManager.getStats(LEGACY_RESOURCE_COUNTS_STATS)
|
|
325
|
+
];
|
|
326
|
+
const orderedStatNames = getResourceCountStatOrder(this._device);
|
|
327
|
+
for (const stats of statsObjects) {
|
|
328
|
+
initializeStats2(stats, orderedStatNames);
|
|
329
|
+
}
|
|
330
|
+
const name2 = this.getStatsName();
|
|
331
|
+
for (const stats of statsObjects) {
|
|
332
|
+
stats.get("Resources Active").decrementCount();
|
|
333
|
+
stats.get(`${name2}s Active`).decrementCount();
|
|
334
|
+
}
|
|
335
|
+
if (profiler) {
|
|
336
|
+
profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
|
|
337
|
+
profiler.statsBookkeepingTimeMs = (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
|
|
338
|
+
}
|
|
202
339
|
}
|
|
203
340
|
/** Called by subclass to track memory allocations */
|
|
204
|
-
trackAllocatedMemory(bytes, name2 = this
|
|
205
|
-
const
|
|
341
|
+
trackAllocatedMemory(bytes, name2 = this.getStatsName()) {
|
|
342
|
+
const profiler = getCpuHotspotProfiler(this._device);
|
|
343
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
344
|
+
const stats = this._device.statsManager.getStats(GPU_TIME_AND_MEMORY_STATS2);
|
|
345
|
+
if (this.allocatedBytes > 0 && this.allocatedBytesName) {
|
|
346
|
+
stats.get("GPU Memory").subtractCount(this.allocatedBytes);
|
|
347
|
+
stats.get(`${this.allocatedBytesName} Memory`).subtractCount(this.allocatedBytes);
|
|
348
|
+
}
|
|
206
349
|
stats.get("GPU Memory").addCount(bytes);
|
|
207
350
|
stats.get(`${name2} Memory`).addCount(bytes);
|
|
351
|
+
if (profiler) {
|
|
352
|
+
profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
|
|
353
|
+
profiler.statsBookkeepingTimeMs = (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
|
|
354
|
+
}
|
|
208
355
|
this.allocatedBytes = bytes;
|
|
356
|
+
this.allocatedBytesName = name2;
|
|
357
|
+
}
|
|
358
|
+
/** Called by subclass to track handle-backed memory allocations separately from owned allocations */
|
|
359
|
+
trackReferencedMemory(bytes, name2 = this.getStatsName()) {
|
|
360
|
+
this.trackAllocatedMemory(bytes, `Referenced ${name2}`);
|
|
209
361
|
}
|
|
210
362
|
/** Called by subclass to track memory deallocations */
|
|
211
|
-
trackDeallocatedMemory(name2 = this
|
|
212
|
-
|
|
363
|
+
trackDeallocatedMemory(name2 = this.getStatsName()) {
|
|
364
|
+
if (this.allocatedBytes === 0) {
|
|
365
|
+
this.allocatedBytesName = null;
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
const profiler = getCpuHotspotProfiler(this._device);
|
|
369
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
370
|
+
const stats = this._device.statsManager.getStats(GPU_TIME_AND_MEMORY_STATS2);
|
|
213
371
|
stats.get("GPU Memory").subtractCount(this.allocatedBytes);
|
|
214
|
-
stats.get(`${name2} Memory`).subtractCount(this.allocatedBytes);
|
|
372
|
+
stats.get(`${this.allocatedBytesName || name2} Memory`).subtractCount(this.allocatedBytes);
|
|
373
|
+
if (profiler) {
|
|
374
|
+
profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
|
|
375
|
+
profiler.statsBookkeepingTimeMs = (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
|
|
376
|
+
}
|
|
215
377
|
this.allocatedBytes = 0;
|
|
378
|
+
this.allocatedBytesName = null;
|
|
379
|
+
}
|
|
380
|
+
/** Called by subclass to deallocate handle-backed memory tracked via trackReferencedMemory() */
|
|
381
|
+
trackDeallocatedReferencedMemory(name2 = this.getStatsName()) {
|
|
382
|
+
this.trackDeallocatedMemory(`Referenced ${name2}`);
|
|
216
383
|
}
|
|
217
384
|
/** Called by resource constructor to track object creation */
|
|
218
385
|
addStats() {
|
|
219
|
-
const
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
386
|
+
const name2 = this.getStatsName();
|
|
387
|
+
const profiler = getCpuHotspotProfiler(this._device);
|
|
388
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
389
|
+
const statsObjects = [
|
|
390
|
+
this._device.statsManager.getStats(RESOURCE_COUNTS_STATS),
|
|
391
|
+
this._device.statsManager.getStats(LEGACY_RESOURCE_COUNTS_STATS)
|
|
392
|
+
];
|
|
393
|
+
const orderedStatNames = getResourceCountStatOrder(this._device);
|
|
394
|
+
for (const stats of statsObjects) {
|
|
395
|
+
initializeStats2(stats, orderedStatNames);
|
|
396
|
+
}
|
|
397
|
+
for (const stats of statsObjects) {
|
|
398
|
+
stats.get("Resources Created").incrementCount();
|
|
399
|
+
stats.get("Resources Active").incrementCount();
|
|
400
|
+
stats.get(`${name2}s Created`).incrementCount();
|
|
401
|
+
stats.get(`${name2}s Active`).incrementCount();
|
|
402
|
+
}
|
|
403
|
+
if (profiler) {
|
|
404
|
+
profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
|
|
405
|
+
profiler.statsBookkeepingTimeMs = (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
|
|
406
|
+
}
|
|
407
|
+
recordTransientCanvasResourceCreate(this._device, name2);
|
|
408
|
+
}
|
|
409
|
+
/** Canonical resource name used for stats buckets. */
|
|
410
|
+
getStatsName() {
|
|
411
|
+
return getCanonicalResourceName(this);
|
|
224
412
|
}
|
|
225
413
|
};
|
|
226
414
|
/** Default properties for resource */
|
|
@@ -238,6 +426,97 @@ function selectivelyMerge(props, defaultProps) {
|
|
|
238
426
|
}
|
|
239
427
|
return mergedProps;
|
|
240
428
|
}
|
|
429
|
+
function initializeStats2(stats, orderedStatNames) {
|
|
430
|
+
const statsMap = stats.stats;
|
|
431
|
+
let addedOrderedStat = false;
|
|
432
|
+
for (const statName of orderedStatNames) {
|
|
433
|
+
if (!statsMap[statName]) {
|
|
434
|
+
stats.get(statName);
|
|
435
|
+
addedOrderedStat = true;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
const statCount = Object.keys(statsMap).length;
|
|
439
|
+
const cachedStats = ORDERED_STATS_CACHE2.get(stats);
|
|
440
|
+
if (!addedOrderedStat && (cachedStats == null ? void 0 : cachedStats.orderedStatNames) === orderedStatNames && cachedStats.statCount === statCount) {
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
const reorderedStats = {};
|
|
444
|
+
let orderedStatNamesSet = ORDERED_STAT_NAME_SET_CACHE2.get(orderedStatNames);
|
|
445
|
+
if (!orderedStatNamesSet) {
|
|
446
|
+
orderedStatNamesSet = new Set(orderedStatNames);
|
|
447
|
+
ORDERED_STAT_NAME_SET_CACHE2.set(orderedStatNames, orderedStatNamesSet);
|
|
448
|
+
}
|
|
449
|
+
for (const statName of orderedStatNames) {
|
|
450
|
+
if (statsMap[statName]) {
|
|
451
|
+
reorderedStats[statName] = statsMap[statName];
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
for (const [statName, stat] of Object.entries(statsMap)) {
|
|
455
|
+
if (!orderedStatNamesSet.has(statName)) {
|
|
456
|
+
reorderedStats[statName] = stat;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
for (const statName of Object.keys(statsMap)) {
|
|
460
|
+
delete statsMap[statName];
|
|
461
|
+
}
|
|
462
|
+
Object.assign(statsMap, reorderedStats);
|
|
463
|
+
ORDERED_STATS_CACHE2.set(stats, { orderedStatNames, statCount });
|
|
464
|
+
}
|
|
465
|
+
function getResourceCountStatOrder(device) {
|
|
466
|
+
return device.type === "webgl" ? WEBGL_RESOURCE_COUNT_STAT_ORDER : BASE_RESOURCE_COUNT_STAT_ORDER;
|
|
467
|
+
}
|
|
468
|
+
function getCpuHotspotProfiler(device) {
|
|
469
|
+
const profiler = device.userData[CPU_HOTSPOT_PROFILER_MODULE];
|
|
470
|
+
return (profiler == null ? void 0 : profiler.enabled) ? profiler : null;
|
|
471
|
+
}
|
|
472
|
+
function getTimestamp() {
|
|
473
|
+
var _a, _b;
|
|
474
|
+
return ((_b = (_a = globalThis.performance) == null ? void 0 : _a.now) == null ? void 0 : _b.call(_a)) ?? Date.now();
|
|
475
|
+
}
|
|
476
|
+
function recordTransientCanvasResourceCreate(device, name2) {
|
|
477
|
+
const profiler = getCpuHotspotProfiler(device);
|
|
478
|
+
if (!profiler || !profiler.activeDefaultFramebufferAcquireDepth) {
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
profiler.transientCanvasResourceCreates = (profiler.transientCanvasResourceCreates || 0) + 1;
|
|
482
|
+
switch (name2) {
|
|
483
|
+
case "Texture":
|
|
484
|
+
profiler.transientCanvasTextureCreates = (profiler.transientCanvasTextureCreates || 0) + 1;
|
|
485
|
+
break;
|
|
486
|
+
case "TextureView":
|
|
487
|
+
profiler.transientCanvasTextureViewCreates = (profiler.transientCanvasTextureViewCreates || 0) + 1;
|
|
488
|
+
break;
|
|
489
|
+
case "Sampler":
|
|
490
|
+
profiler.transientCanvasSamplerCreates = (profiler.transientCanvasSamplerCreates || 0) + 1;
|
|
491
|
+
break;
|
|
492
|
+
case "Framebuffer":
|
|
493
|
+
profiler.transientCanvasFramebufferCreates = (profiler.transientCanvasFramebufferCreates || 0) + 1;
|
|
494
|
+
break;
|
|
495
|
+
default:
|
|
496
|
+
break;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
function getCanonicalResourceName(resource) {
|
|
500
|
+
let prototype = Object.getPrototypeOf(resource);
|
|
501
|
+
while (prototype) {
|
|
502
|
+
const parentPrototype = Object.getPrototypeOf(prototype);
|
|
503
|
+
if (!parentPrototype || parentPrototype === Resource.prototype) {
|
|
504
|
+
return getPrototypeToStringTag(prototype) || resource[Symbol.toStringTag] || resource.constructor.name;
|
|
505
|
+
}
|
|
506
|
+
prototype = parentPrototype;
|
|
507
|
+
}
|
|
508
|
+
return resource[Symbol.toStringTag] || resource.constructor.name;
|
|
509
|
+
}
|
|
510
|
+
function getPrototypeToStringTag(prototype) {
|
|
511
|
+
const descriptor = Object.getOwnPropertyDescriptor(prototype, Symbol.toStringTag);
|
|
512
|
+
if (typeof (descriptor == null ? void 0 : descriptor.get) === "function") {
|
|
513
|
+
return descriptor.get.call(prototype);
|
|
514
|
+
}
|
|
515
|
+
if (typeof (descriptor == null ? void 0 : descriptor.value) === "string") {
|
|
516
|
+
return descriptor.value;
|
|
517
|
+
}
|
|
518
|
+
return null;
|
|
519
|
+
}
|
|
241
520
|
|
|
242
521
|
// dist/adapter/resources/buffer.js
|
|
243
522
|
var _Buffer = class extends Resource {
|
|
@@ -277,15 +556,23 @@ var _Buffer = class extends Resource {
|
|
|
277
556
|
/** A partial CPU-side copy of the data in this buffer, for debugging purposes */
|
|
278
557
|
debugData = new ArrayBuffer(0);
|
|
279
558
|
/** This doesn't handle partial non-zero offset updates correctly */
|
|
280
|
-
_setDebugData(data,
|
|
281
|
-
|
|
559
|
+
_setDebugData(data, _byteOffset, byteLength) {
|
|
560
|
+
let arrayBufferView = null;
|
|
561
|
+
let arrayBuffer2;
|
|
562
|
+
if (ArrayBuffer.isView(data)) {
|
|
563
|
+
arrayBufferView = data;
|
|
564
|
+
arrayBuffer2 = data.buffer;
|
|
565
|
+
} else {
|
|
566
|
+
arrayBuffer2 = data;
|
|
567
|
+
}
|
|
282
568
|
const debugDataLength = Math.min(data ? data.byteLength : byteLength, _Buffer.DEBUG_DATA_MAX_LENGTH);
|
|
283
569
|
if (arrayBuffer2 === null) {
|
|
284
570
|
this.debugData = new ArrayBuffer(debugDataLength);
|
|
285
|
-
} else if (byteOffset === 0 && byteLength === arrayBuffer2.byteLength) {
|
|
286
|
-
this.debugData = arrayBuffer2.slice(0, debugDataLength);
|
|
287
571
|
} else {
|
|
288
|
-
|
|
572
|
+
const sourceByteOffset = Math.min((arrayBufferView == null ? void 0 : arrayBufferView.byteOffset) || 0, arrayBuffer2.byteLength);
|
|
573
|
+
const availableByteLength = Math.max(0, arrayBuffer2.byteLength - sourceByteOffset);
|
|
574
|
+
const copyByteLength = Math.min(debugDataLength, availableByteLength);
|
|
575
|
+
this.debugData = new Uint8Array(arrayBuffer2, sourceByteOffset, copyByteLength).slice().buffer;
|
|
289
576
|
}
|
|
290
577
|
}
|
|
291
578
|
};
|
|
@@ -481,6 +768,7 @@ var float32_renderable = "float32-renderable-webgl";
|
|
|
481
768
|
var float16_renderable = "float16-renderable-webgl";
|
|
482
769
|
var rgb9e5ufloat_renderable = "rgb9e5ufloat-renderable-webgl";
|
|
483
770
|
var snorm8_renderable = "snorm8-renderable-webgl";
|
|
771
|
+
var norm16_webgl = "norm16-webgl";
|
|
484
772
|
var norm16_renderable = "norm16-renderable-webgl";
|
|
485
773
|
var snorm16_renderable = "snorm16-renderable-webgl";
|
|
486
774
|
var float32_filterable = "float32-filterable";
|
|
@@ -514,16 +802,16 @@ var TEXTURE_FORMAT_COLOR_DEPTH_TABLE = {
|
|
|
514
802
|
"rgba8sint": {},
|
|
515
803
|
"bgra8unorm": {},
|
|
516
804
|
"bgra8unorm-srgb": {},
|
|
517
|
-
"r16unorm": { f: norm16_renderable },
|
|
518
|
-
"rg16unorm": { render: norm16_renderable },
|
|
519
|
-
"rgb16unorm-webgl": { f:
|
|
805
|
+
"r16unorm": { f: norm16_webgl, render: norm16_renderable },
|
|
806
|
+
"rg16unorm": { f: norm16_webgl, render: norm16_renderable },
|
|
807
|
+
"rgb16unorm-webgl": { f: norm16_webgl, render: false },
|
|
520
808
|
// rgb not renderable
|
|
521
|
-
"rgba16unorm": { render: norm16_renderable },
|
|
522
|
-
"r16snorm": { f: snorm16_renderable },
|
|
523
|
-
"rg16snorm": { render: snorm16_renderable },
|
|
524
|
-
"rgb16snorm-webgl": { f:
|
|
809
|
+
"rgba16unorm": { f: norm16_webgl, render: norm16_renderable },
|
|
810
|
+
"r16snorm": { f: norm16_webgl, render: snorm16_renderable },
|
|
811
|
+
"rg16snorm": { f: norm16_webgl, render: snorm16_renderable },
|
|
812
|
+
"rgb16snorm-webgl": { f: norm16_webgl, render: false },
|
|
525
813
|
// rgb not renderable
|
|
526
|
-
"rgba16snorm": { render: snorm16_renderable },
|
|
814
|
+
"rgba16snorm": { f: norm16_webgl, render: snorm16_renderable },
|
|
527
815
|
"r16uint": {},
|
|
528
816
|
"rg16uint": {},
|
|
529
817
|
"rgba16uint": {},
|
|
@@ -626,7 +914,7 @@ var TEXTURE_FORMAT_COMPRESSED_TABLE = {
|
|
|
626
914
|
// WEBGL_compressed_texture_pvrtc
|
|
627
915
|
"pvrtc-rgb4unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
628
916
|
"pvrtc-rgba4unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
629
|
-
"pvrtc-
|
|
917
|
+
"pvrtc-rgb2unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
630
918
|
"pvrtc-rgba2unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
631
919
|
// WEBGL_compressed_texture_etc1
|
|
632
920
|
"etc1-rbg-unorm-webgl": { f: texture_compression_etc1_webgl },
|
|
@@ -687,10 +975,13 @@ var TextureFormatDecoder = class {
|
|
|
687
975
|
};
|
|
688
976
|
var textureFormatDecoder = new TextureFormatDecoder();
|
|
689
977
|
function computeTextureMemoryLayout({ format, width, height, depth, byteAlignment }) {
|
|
690
|
-
const
|
|
691
|
-
const
|
|
978
|
+
const formatInfo = textureFormatDecoder.getInfo(format);
|
|
979
|
+
const { bytesPerPixel, bytesPerBlock = bytesPerPixel, blockWidth = 1, blockHeight = 1, compressed = false } = formatInfo;
|
|
980
|
+
const blockColumns = compressed ? Math.ceil(width / blockWidth) : width;
|
|
981
|
+
const blockRows = compressed ? Math.ceil(height / blockHeight) : height;
|
|
982
|
+
const unpaddedBytesPerRow = blockColumns * bytesPerBlock;
|
|
692
983
|
const bytesPerRow = Math.ceil(unpaddedBytesPerRow / byteAlignment) * byteAlignment;
|
|
693
|
-
const rowsPerImage =
|
|
984
|
+
const rowsPerImage = blockRows;
|
|
694
985
|
const byteLength = bytesPerRow * rowsPerImage * depth;
|
|
695
986
|
return {
|
|
696
987
|
bytesPerPixel,
|
|
@@ -716,7 +1007,8 @@ function getTextureFormatCapabilities(format) {
|
|
|
716
1007
|
const isSigned = formatInfo == null ? void 0 : formatInfo.signed;
|
|
717
1008
|
const isInteger = formatInfo == null ? void 0 : formatInfo.integer;
|
|
718
1009
|
const isWebGLSpecific = formatInfo == null ? void 0 : formatInfo.webgl;
|
|
719
|
-
|
|
1010
|
+
const isCompressed = Boolean(formatInfo == null ? void 0 : formatInfo.compressed);
|
|
1011
|
+
formatCapabilities.render &&= !isDepthStencil && !isCompressed;
|
|
720
1012
|
formatCapabilities.filter &&= !isDepthStencil && !isSigned && !isInteger && !isWebGLSpecific;
|
|
721
1013
|
return formatCapabilities;
|
|
722
1014
|
}
|
|
@@ -728,6 +1020,7 @@ function getTextureFormatInfo(format) {
|
|
|
728
1020
|
formatInfo.bytesPerPixel = 1;
|
|
729
1021
|
formatInfo.srgb = false;
|
|
730
1022
|
formatInfo.compressed = true;
|
|
1023
|
+
formatInfo.bytesPerBlock = getCompressedTextureBlockByteLength(format);
|
|
731
1024
|
const blockSize = getCompressedTextureBlockSize(format);
|
|
732
1025
|
if (blockSize) {
|
|
733
1026
|
formatInfo.blockWidth = blockSize.blockWidth;
|
|
@@ -740,7 +1033,7 @@ function getTextureFormatInfo(format) {
|
|
|
740
1033
|
const dataType = `${type}${length}`;
|
|
741
1034
|
const decodedType = getDataTypeInfo(dataType);
|
|
742
1035
|
const bits = decodedType.byteLength * 8;
|
|
743
|
-
const components = channels.length;
|
|
1036
|
+
const components = (channels == null ? void 0 : channels.length) ?? 1;
|
|
744
1037
|
const bitsPerChannel = [
|
|
745
1038
|
bits,
|
|
746
1039
|
components >= 2 ? bits : 0,
|
|
@@ -757,7 +1050,7 @@ function getTextureFormatInfo(format) {
|
|
|
757
1050
|
signed: decodedType.signed,
|
|
758
1051
|
normalized: decodedType.normalized,
|
|
759
1052
|
bitsPerChannel,
|
|
760
|
-
bytesPerPixel: decodedType.byteLength *
|
|
1053
|
+
bytesPerPixel: decodedType.byteLength * components,
|
|
761
1054
|
packed: formatInfo.packed,
|
|
762
1055
|
srgb: formatInfo.srgb
|
|
763
1056
|
};
|
|
@@ -814,8 +1107,29 @@ function getCompressedTextureBlockSize(format) {
|
|
|
814
1107
|
const [, blockWidth, blockHeight] = matches;
|
|
815
1108
|
return { blockWidth: Number(blockWidth), blockHeight: Number(blockHeight) };
|
|
816
1109
|
}
|
|
1110
|
+
if (format.startsWith("bc") || format.startsWith("etc1") || format.startsWith("etc2") || format.startsWith("eac") || format.startsWith("atc")) {
|
|
1111
|
+
return { blockWidth: 4, blockHeight: 4 };
|
|
1112
|
+
}
|
|
1113
|
+
if (format.startsWith("pvrtc-rgb4") || format.startsWith("pvrtc-rgba4")) {
|
|
1114
|
+
return { blockWidth: 4, blockHeight: 4 };
|
|
1115
|
+
}
|
|
1116
|
+
if (format.startsWith("pvrtc-rgb2") || format.startsWith("pvrtc-rgba2")) {
|
|
1117
|
+
return { blockWidth: 8, blockHeight: 4 };
|
|
1118
|
+
}
|
|
817
1119
|
return null;
|
|
818
1120
|
}
|
|
1121
|
+
function getCompressedTextureBlockByteLength(format) {
|
|
1122
|
+
if (format.startsWith("bc1") || format.startsWith("bc4") || format.startsWith("etc1") || format.startsWith("etc2-rgb8") || format.startsWith("etc2-rgb8a1") || format.startsWith("eac-r11") || format === "atc-rgb-unorm-webgl") {
|
|
1123
|
+
return 8;
|
|
1124
|
+
}
|
|
1125
|
+
if (format.startsWith("bc2") || format.startsWith("bc3") || format.startsWith("bc5") || format.startsWith("bc6h") || format.startsWith("bc7") || format.startsWith("etc2-rgba8") || format.startsWith("eac-rg11") || format.startsWith("astc") || format === "atc-rgba-unorm-webgl" || format === "atc-rgbai-unorm-webgl") {
|
|
1126
|
+
return 16;
|
|
1127
|
+
}
|
|
1128
|
+
if (format.startsWith("pvrtc")) {
|
|
1129
|
+
return 8;
|
|
1130
|
+
}
|
|
1131
|
+
return 16;
|
|
1132
|
+
}
|
|
819
1133
|
|
|
820
1134
|
// dist/image-utils/image-types.js
|
|
821
1135
|
function isExternalImage(data) {
|
|
@@ -877,6 +1191,8 @@ var _Device = class {
|
|
|
877
1191
|
/** Used by other luma.gl modules to store data on the device */
|
|
878
1192
|
_moduleData = {};
|
|
879
1193
|
_textureCaps = {};
|
|
1194
|
+
/** Internal timestamp query set used when GPU timing collection is enabled for this device. */
|
|
1195
|
+
_debugGPUTimeQuery = null;
|
|
880
1196
|
constructor(props) {
|
|
881
1197
|
this.props = { ..._Device.defaultProps, ...props };
|
|
882
1198
|
this.id = this.props.id || uid(this[Symbol.toStringTag].toLowerCase());
|
|
@@ -930,6 +1246,16 @@ var _Device = class {
|
|
|
930
1246
|
isTextureFormatCompressed(format) {
|
|
931
1247
|
return textureFormatDecoder.isCompressed(format);
|
|
932
1248
|
}
|
|
1249
|
+
/** Returns the compressed texture formats that can be created and sampled on this device */
|
|
1250
|
+
getSupportedCompressedTextureFormats() {
|
|
1251
|
+
const supportedFormats = [];
|
|
1252
|
+
for (const format of Object.keys(getTextureFormatTable())) {
|
|
1253
|
+
if (this.isTextureFormatCompressed(format) && this.isTextureFormatSupported(format)) {
|
|
1254
|
+
supportedFormats.push(format);
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
return supportedFormats;
|
|
1258
|
+
}
|
|
933
1259
|
// DEBUG METHODS
|
|
934
1260
|
pushDebugGroup(groupLabel) {
|
|
935
1261
|
this.commandEncoder.pushDebugGroup(groupLabel);
|
|
@@ -1008,6 +1334,70 @@ or create a device with the 'debug: true' prop.`;
|
|
|
1008
1334
|
beginComputePass(props) {
|
|
1009
1335
|
return this.commandEncoder.beginComputePass(props);
|
|
1010
1336
|
}
|
|
1337
|
+
/**
|
|
1338
|
+
* Generate mipmaps for a WebGPU texture.
|
|
1339
|
+
* WebGPU textures must be created up front with the required mip count, usage flags, and a format that supports the chosen generation path.
|
|
1340
|
+
* WebGL uses `Texture.generateMipmapsWebGL()` directly because the backend manages mip generation on the texture object itself.
|
|
1341
|
+
*/
|
|
1342
|
+
generateMipmapsWebGPU(_texture) {
|
|
1343
|
+
throw new Error("not implemented");
|
|
1344
|
+
}
|
|
1345
|
+
/** Internal helper for creating a shareable WebGL render-pipeline implementation. */
|
|
1346
|
+
_createSharedRenderPipelineWebGL(_props) {
|
|
1347
|
+
throw new Error("_createSharedRenderPipelineWebGL() not implemented");
|
|
1348
|
+
}
|
|
1349
|
+
/**
|
|
1350
|
+
* Internal helper that returns `true` when timestamp-query GPU timing should be
|
|
1351
|
+
* collected for this device.
|
|
1352
|
+
*/
|
|
1353
|
+
_supportsDebugGPUTime() {
|
|
1354
|
+
return this.features.has("timestamp-query") && Boolean(this.props.debug || this.props.debugGPUTime);
|
|
1355
|
+
}
|
|
1356
|
+
/**
|
|
1357
|
+
* Internal helper that enables device-managed GPU timing collection on the
|
|
1358
|
+
* default command encoder. Reuses the existing query set if timing is already enabled.
|
|
1359
|
+
*
|
|
1360
|
+
* @param queryCount - Number of timestamp slots reserved for profiled passes.
|
|
1361
|
+
* @returns The device-managed timestamp QuerySet, or `null` when timing is not supported or could not be enabled.
|
|
1362
|
+
*/
|
|
1363
|
+
_enableDebugGPUTime(queryCount = 256) {
|
|
1364
|
+
if (!this._supportsDebugGPUTime()) {
|
|
1365
|
+
return null;
|
|
1366
|
+
}
|
|
1367
|
+
if (this._debugGPUTimeQuery) {
|
|
1368
|
+
return this._debugGPUTimeQuery;
|
|
1369
|
+
}
|
|
1370
|
+
try {
|
|
1371
|
+
this._debugGPUTimeQuery = this.createQuerySet({ type: "timestamp", count: queryCount });
|
|
1372
|
+
this.commandEncoder = this.createCommandEncoder({
|
|
1373
|
+
id: this.commandEncoder.props.id,
|
|
1374
|
+
timeProfilingQuerySet: this._debugGPUTimeQuery
|
|
1375
|
+
});
|
|
1376
|
+
} catch {
|
|
1377
|
+
this._debugGPUTimeQuery = null;
|
|
1378
|
+
}
|
|
1379
|
+
return this._debugGPUTimeQuery;
|
|
1380
|
+
}
|
|
1381
|
+
/**
|
|
1382
|
+
* Internal helper that disables device-managed GPU timing collection and restores
|
|
1383
|
+
* the default command encoder to an unprofiled state.
|
|
1384
|
+
*/
|
|
1385
|
+
_disableDebugGPUTime() {
|
|
1386
|
+
if (!this._debugGPUTimeQuery) {
|
|
1387
|
+
return;
|
|
1388
|
+
}
|
|
1389
|
+
if (this.commandEncoder.getTimeProfilingQuerySet() === this._debugGPUTimeQuery) {
|
|
1390
|
+
this.commandEncoder = this.createCommandEncoder({
|
|
1391
|
+
id: this.commandEncoder.props.id
|
|
1392
|
+
});
|
|
1393
|
+
}
|
|
1394
|
+
this._debugGPUTimeQuery.destroy();
|
|
1395
|
+
this._debugGPUTimeQuery = null;
|
|
1396
|
+
}
|
|
1397
|
+
/** Internal helper that returns `true` when device-managed GPU timing is currently active. */
|
|
1398
|
+
_isDebugGPUTimeEnabled() {
|
|
1399
|
+
return this._debugGPUTimeQuery !== null;
|
|
1400
|
+
}
|
|
1011
1401
|
// DEPRECATED METHODS
|
|
1012
1402
|
/** @deprecated Use getDefaultCanvasContext() */
|
|
1013
1403
|
getCanvasContext() {
|
|
@@ -1115,7 +1505,8 @@ __publicField(Device, "defaultProps", {
|
|
|
1115
1505
|
onVisibilityChange: (context) => log.log(1, `${context} Visibility changed ${context.isVisible}`)(),
|
|
1116
1506
|
onDevicePixelRatioChange: (context, info) => log.log(1, `${context} DPR changed ${info.oldRatio} => ${context.devicePixelRatio}`)(),
|
|
1117
1507
|
// Debug flags
|
|
1118
|
-
debug:
|
|
1508
|
+
debug: getDefaultDebugValue(),
|
|
1509
|
+
debugGPUTime: false,
|
|
1119
1510
|
debugShaders: log.get("debug-shaders") || void 0,
|
|
1120
1511
|
debugFramebuffers: Boolean(log.get("debug-framebuffers")),
|
|
1121
1512
|
debugFactories: Boolean(log.get("debug-factories")),
|
|
@@ -1126,9 +1517,11 @@ __publicField(Device, "defaultProps", {
|
|
|
1126
1517
|
// Experimental
|
|
1127
1518
|
_reuseDevices: false,
|
|
1128
1519
|
_requestMaxLimits: true,
|
|
1129
|
-
_cacheShaders:
|
|
1130
|
-
|
|
1131
|
-
|
|
1520
|
+
_cacheShaders: true,
|
|
1521
|
+
_destroyShaders: false,
|
|
1522
|
+
_cachePipelines: true,
|
|
1523
|
+
_sharePipelines: true,
|
|
1524
|
+
_destroyPipelines: false,
|
|
1132
1525
|
// TODO - Change these after confirming things work as expected
|
|
1133
1526
|
_initializeFeatures: true,
|
|
1134
1527
|
_disabledFeatures: {
|
|
@@ -1137,6 +1530,25 @@ __publicField(Device, "defaultProps", {
|
|
|
1137
1530
|
// INTERNAL
|
|
1138
1531
|
_handle: void 0
|
|
1139
1532
|
});
|
|
1533
|
+
function _getDefaultDebugValue(logDebugValue, nodeEnv) {
|
|
1534
|
+
if (logDebugValue !== void 0 && logDebugValue !== null) {
|
|
1535
|
+
return Boolean(logDebugValue);
|
|
1536
|
+
}
|
|
1537
|
+
if (nodeEnv !== void 0) {
|
|
1538
|
+
return nodeEnv !== "production";
|
|
1539
|
+
}
|
|
1540
|
+
return false;
|
|
1541
|
+
}
|
|
1542
|
+
function getDefaultDebugValue() {
|
|
1543
|
+
return _getDefaultDebugValue(log.get("debug"), getNodeEnv());
|
|
1544
|
+
}
|
|
1545
|
+
function getNodeEnv() {
|
|
1546
|
+
const processObject = globalThis.process;
|
|
1547
|
+
if (!(processObject == null ? void 0 : processObject.env)) {
|
|
1548
|
+
return void 0;
|
|
1549
|
+
}
|
|
1550
|
+
return processObject.env["NODE_ENV"];
|
|
1551
|
+
}
|
|
1140
1552
|
|
|
1141
1553
|
// dist/adapter/luma.js
|
|
1142
1554
|
var STARTUP_MESSAGE = "set luma.log.level=1 (or higher) to trace rendering";
|
|
@@ -1156,7 +1568,7 @@ var _Luma = class {
|
|
|
1156
1568
|
VERSION = (
|
|
1157
1569
|
// Version detection using build plugin
|
|
1158
1570
|
// @ts-expect-error no-undef
|
|
1159
|
-
true ? "9.3.0-alpha.
|
|
1571
|
+
true ? "9.3.0-alpha.6" : "running from source"
|
|
1160
1572
|
);
|
|
1161
1573
|
spector;
|
|
1162
1574
|
preregisteredAdapters = /* @__PURE__ */ new Map();
|
|
@@ -1321,9 +1733,91 @@ function getPageLoadPromise() {
|
|
|
1321
1733
|
return pageLoadPromise;
|
|
1322
1734
|
}
|
|
1323
1735
|
|
|
1324
|
-
// dist/adapter/canvas-
|
|
1736
|
+
// dist/adapter/canvas-surface.js
|
|
1325
1737
|
var import_env2 = require("@probe.gl/env");
|
|
1326
1738
|
|
|
1739
|
+
// dist/adapter/canvas-observer.js
|
|
1740
|
+
var CanvasObserver = class {
|
|
1741
|
+
props;
|
|
1742
|
+
_resizeObserver;
|
|
1743
|
+
_intersectionObserver;
|
|
1744
|
+
_observeDevicePixelRatioTimeout = null;
|
|
1745
|
+
_observeDevicePixelRatioMediaQuery = null;
|
|
1746
|
+
_handleDevicePixelRatioChange = () => this._refreshDevicePixelRatio();
|
|
1747
|
+
_trackPositionInterval = null;
|
|
1748
|
+
_started = false;
|
|
1749
|
+
get started() {
|
|
1750
|
+
return this._started;
|
|
1751
|
+
}
|
|
1752
|
+
constructor(props) {
|
|
1753
|
+
this.props = props;
|
|
1754
|
+
}
|
|
1755
|
+
start() {
|
|
1756
|
+
if (this._started || !this.props.canvas) {
|
|
1757
|
+
return;
|
|
1758
|
+
}
|
|
1759
|
+
this._started = true;
|
|
1760
|
+
this._intersectionObserver ||= new IntersectionObserver((entries) => this.props.onIntersection(entries));
|
|
1761
|
+
this._resizeObserver ||= new ResizeObserver((entries) => this.props.onResize(entries));
|
|
1762
|
+
this._intersectionObserver.observe(this.props.canvas);
|
|
1763
|
+
try {
|
|
1764
|
+
this._resizeObserver.observe(this.props.canvas, { box: "device-pixel-content-box" });
|
|
1765
|
+
} catch {
|
|
1766
|
+
this._resizeObserver.observe(this.props.canvas, { box: "content-box" });
|
|
1767
|
+
}
|
|
1768
|
+
this._observeDevicePixelRatioTimeout = setTimeout(() => this._refreshDevicePixelRatio(), 0);
|
|
1769
|
+
if (this.props.trackPosition) {
|
|
1770
|
+
this._trackPosition();
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
stop() {
|
|
1774
|
+
var _a, _b;
|
|
1775
|
+
if (!this._started) {
|
|
1776
|
+
return;
|
|
1777
|
+
}
|
|
1778
|
+
this._started = false;
|
|
1779
|
+
if (this._observeDevicePixelRatioTimeout) {
|
|
1780
|
+
clearTimeout(this._observeDevicePixelRatioTimeout);
|
|
1781
|
+
this._observeDevicePixelRatioTimeout = null;
|
|
1782
|
+
}
|
|
1783
|
+
if (this._observeDevicePixelRatioMediaQuery) {
|
|
1784
|
+
this._observeDevicePixelRatioMediaQuery.removeEventListener("change", this._handleDevicePixelRatioChange);
|
|
1785
|
+
this._observeDevicePixelRatioMediaQuery = null;
|
|
1786
|
+
}
|
|
1787
|
+
if (this._trackPositionInterval) {
|
|
1788
|
+
clearInterval(this._trackPositionInterval);
|
|
1789
|
+
this._trackPositionInterval = null;
|
|
1790
|
+
}
|
|
1791
|
+
(_a = this._resizeObserver) == null ? void 0 : _a.disconnect();
|
|
1792
|
+
(_b = this._intersectionObserver) == null ? void 0 : _b.disconnect();
|
|
1793
|
+
}
|
|
1794
|
+
_refreshDevicePixelRatio() {
|
|
1795
|
+
var _a;
|
|
1796
|
+
if (!this._started) {
|
|
1797
|
+
return;
|
|
1798
|
+
}
|
|
1799
|
+
this.props.onDevicePixelRatioChange();
|
|
1800
|
+
(_a = this._observeDevicePixelRatioMediaQuery) == null ? void 0 : _a.removeEventListener("change", this._handleDevicePixelRatioChange);
|
|
1801
|
+
this._observeDevicePixelRatioMediaQuery = matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
|
|
1802
|
+
this._observeDevicePixelRatioMediaQuery.addEventListener("change", this._handleDevicePixelRatioChange, { once: true });
|
|
1803
|
+
}
|
|
1804
|
+
_trackPosition(intervalMs = 100) {
|
|
1805
|
+
if (this._trackPositionInterval) {
|
|
1806
|
+
return;
|
|
1807
|
+
}
|
|
1808
|
+
this._trackPositionInterval = setInterval(() => {
|
|
1809
|
+
if (!this._started) {
|
|
1810
|
+
if (this._trackPositionInterval) {
|
|
1811
|
+
clearInterval(this._trackPositionInterval);
|
|
1812
|
+
this._trackPositionInterval = null;
|
|
1813
|
+
}
|
|
1814
|
+
} else {
|
|
1815
|
+
this.props.onPositionChange();
|
|
1816
|
+
}
|
|
1817
|
+
}, intervalMs);
|
|
1818
|
+
}
|
|
1819
|
+
};
|
|
1820
|
+
|
|
1327
1821
|
// dist/utils/promise-utils.js
|
|
1328
1822
|
function withResolvers() {
|
|
1329
1823
|
let resolve;
|
|
@@ -1335,8 +1829,22 @@ function withResolvers() {
|
|
|
1335
1829
|
return { promise, resolve, reject };
|
|
1336
1830
|
}
|
|
1337
1831
|
|
|
1338
|
-
// dist/
|
|
1339
|
-
|
|
1832
|
+
// dist/utils/assert.js
|
|
1833
|
+
function assert(condition, message) {
|
|
1834
|
+
var _a;
|
|
1835
|
+
if (!condition) {
|
|
1836
|
+
const error = new Error(message ?? "luma.gl assertion failed.");
|
|
1837
|
+
(_a = Error.captureStackTrace) == null ? void 0 : _a.call(Error, error, assert);
|
|
1838
|
+
throw error;
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
function assertDefined(value, message) {
|
|
1842
|
+
assert(value, message);
|
|
1843
|
+
return value;
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
// dist/adapter/canvas-surface.js
|
|
1847
|
+
var _CanvasSurface = class {
|
|
1340
1848
|
static isHTMLCanvas(canvas) {
|
|
1341
1849
|
return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement;
|
|
1342
1850
|
}
|
|
@@ -1372,10 +1880,7 @@ var _CanvasContext = class {
|
|
|
1372
1880
|
drawingBufferHeight;
|
|
1373
1881
|
/** Resolves when the canvas is initialized, i.e. when the ResizeObserver has updated the pixel size */
|
|
1374
1882
|
_initializedResolvers = withResolvers();
|
|
1375
|
-
|
|
1376
|
-
_resizeObserver;
|
|
1377
|
-
/** IntersectionObserver to track canvas visibility changes */
|
|
1378
|
-
_intersectionObserver;
|
|
1883
|
+
_canvasObserver;
|
|
1379
1884
|
/** Position of the canvas in the document, updated by a timer */
|
|
1380
1885
|
_position = [0, 0];
|
|
1381
1886
|
/** Whether this canvas context has been destroyed */
|
|
@@ -1387,7 +1892,7 @@ var _CanvasContext = class {
|
|
|
1387
1892
|
}
|
|
1388
1893
|
constructor(props) {
|
|
1389
1894
|
var _a, _b;
|
|
1390
|
-
this.props = { ...
|
|
1895
|
+
this.props = { ..._CanvasSurface.defaultProps, ...props };
|
|
1391
1896
|
props = this.props;
|
|
1392
1897
|
this.initialized = this._initializedResolvers.promise;
|
|
1393
1898
|
if (!(0, import_env2.isBrowser)()) {
|
|
@@ -1399,11 +1904,11 @@ var _CanvasContext = class {
|
|
|
1399
1904
|
} else {
|
|
1400
1905
|
this.canvas = props.canvas;
|
|
1401
1906
|
}
|
|
1402
|
-
if (
|
|
1907
|
+
if (_CanvasSurface.isHTMLCanvas(this.canvas)) {
|
|
1403
1908
|
this.id = props.id || this.canvas.id;
|
|
1404
1909
|
this.type = "html-canvas";
|
|
1405
1910
|
this.htmlCanvas = this.canvas;
|
|
1406
|
-
} else if (
|
|
1911
|
+
} else if (_CanvasSurface.isOffscreenCanvas(this.canvas)) {
|
|
1407
1912
|
this.id = props.id || "offscreen-canvas";
|
|
1408
1913
|
this.type = "offscreen-canvas";
|
|
1409
1914
|
this.offscreenCanvas = this.canvas;
|
|
@@ -1419,23 +1924,21 @@ var _CanvasContext = class {
|
|
|
1419
1924
|
this.drawingBufferHeight = this.canvas.height;
|
|
1420
1925
|
this.devicePixelRatio = globalThis.devicePixelRatio || 1;
|
|
1421
1926
|
this._position = [0, 0];
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
this.
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
}
|
|
1431
|
-
setTimeout(() => this._observeDevicePixelRatio(), 0);
|
|
1432
|
-
if (this.props.trackPosition) {
|
|
1433
|
-
this._trackPosition();
|
|
1434
|
-
}
|
|
1435
|
-
}
|
|
1927
|
+
this._canvasObserver = new CanvasObserver({
|
|
1928
|
+
canvas: this.htmlCanvas,
|
|
1929
|
+
trackPosition: this.props.trackPosition,
|
|
1930
|
+
onResize: (entries) => this._handleResize(entries),
|
|
1931
|
+
onIntersection: (entries) => this._handleIntersection(entries),
|
|
1932
|
+
onDevicePixelRatioChange: () => this._observeDevicePixelRatio(),
|
|
1933
|
+
onPositionChange: () => this.updatePosition()
|
|
1934
|
+
});
|
|
1436
1935
|
}
|
|
1437
1936
|
destroy() {
|
|
1438
|
-
this.destroyed
|
|
1937
|
+
if (!this.destroyed) {
|
|
1938
|
+
this.destroyed = true;
|
|
1939
|
+
this._stopObservers();
|
|
1940
|
+
this.device = null;
|
|
1941
|
+
}
|
|
1439
1942
|
}
|
|
1440
1943
|
setProps(props) {
|
|
1441
1944
|
if ("useDevicePixels" in props) {
|
|
@@ -1449,59 +1952,36 @@ var _CanvasContext = class {
|
|
|
1449
1952
|
this._resizeDrawingBufferIfNeeded();
|
|
1450
1953
|
return this._getCurrentFramebuffer(options);
|
|
1451
1954
|
}
|
|
1452
|
-
// SIZE METHODS
|
|
1453
|
-
/**
|
|
1454
|
-
* Returns the size covered by the canvas in CSS pixels
|
|
1455
|
-
* @note This can be different from the actual device pixel size of a canvas due to DPR scaling, and rounding to integer pixels
|
|
1456
|
-
* @note This is independent of the canvas' internal drawing buffer size (.width, .height).
|
|
1457
|
-
*/
|
|
1458
1955
|
getCSSSize() {
|
|
1459
1956
|
return [this.cssWidth, this.cssHeight];
|
|
1460
1957
|
}
|
|
1461
1958
|
getPosition() {
|
|
1462
1959
|
return this._position;
|
|
1463
1960
|
}
|
|
1464
|
-
/**
|
|
1465
|
-
* Returns the size covered by the canvas in actual device pixels.
|
|
1466
|
-
* @note This can be different from the 'CSS' size of a canvas due to DPR scaling, and rounding to integer pixels
|
|
1467
|
-
* @note This is independent of the canvas' internal drawing buffer size (.width, .height).
|
|
1468
|
-
*/
|
|
1469
1961
|
getDevicePixelSize() {
|
|
1470
1962
|
return [this.devicePixelWidth, this.devicePixelHeight];
|
|
1471
1963
|
}
|
|
1472
|
-
/** Get the drawing buffer size (number of pixels GPU is rendering into, can be different from CSS size) */
|
|
1473
1964
|
getDrawingBufferSize() {
|
|
1474
1965
|
return [this.drawingBufferWidth, this.drawingBufferHeight];
|
|
1475
1966
|
}
|
|
1476
|
-
/** Returns the biggest allowed framebuffer size. @todo Allow the application to limit this? */
|
|
1477
1967
|
getMaxDrawingBufferSize() {
|
|
1478
1968
|
const maxTextureDimension = this.device.limits.maxTextureDimension2D;
|
|
1479
1969
|
return [maxTextureDimension, maxTextureDimension];
|
|
1480
1970
|
}
|
|
1481
|
-
/**
|
|
1482
|
-
* Update the canvas drawing buffer size.
|
|
1483
|
-
* @note - Called automatically if props.autoResize is true.
|
|
1484
|
-
* @note - Defers update of drawing buffer size until framebuffer is requested to avoid flicker
|
|
1485
|
-
* (resizing clears the drawing buffer)!
|
|
1486
|
-
*/
|
|
1487
1971
|
setDrawingBufferSize(width, height) {
|
|
1488
|
-
|
|
1489
|
-
|
|
1972
|
+
width = Math.floor(width);
|
|
1973
|
+
height = Math.floor(height);
|
|
1974
|
+
if (this.drawingBufferWidth === width && this.drawingBufferHeight === height) {
|
|
1975
|
+
return;
|
|
1976
|
+
}
|
|
1977
|
+
this.drawingBufferWidth = width;
|
|
1978
|
+
this.drawingBufferHeight = height;
|
|
1490
1979
|
this._needsDrawingBufferResize = true;
|
|
1491
1980
|
}
|
|
1492
|
-
/**
|
|
1493
|
-
* Returns the current DPR (number of physical pixels per CSS pixel), if props.useDevicePixels is true
|
|
1494
|
-
* @note This can be a fractional (non-integer) number, e.g. when the user zooms in the browser.
|
|
1495
|
-
* @note This function handles the non-HTML canvas cases
|
|
1496
|
-
*/
|
|
1497
1981
|
getDevicePixelRatio() {
|
|
1498
|
-
const
|
|
1499
|
-
return
|
|
1982
|
+
const devicePixelRatio2 = typeof window !== "undefined" && window.devicePixelRatio;
|
|
1983
|
+
return devicePixelRatio2 || 1;
|
|
1500
1984
|
}
|
|
1501
|
-
// DEPRECATED METHODS
|
|
1502
|
-
/**
|
|
1503
|
-
* Maps CSS pixel position to device pixel position
|
|
1504
|
-
*/
|
|
1505
1985
|
cssToDevicePixels(cssPixel, yInvert = true) {
|
|
1506
1986
|
const ratio = this.cssToDeviceRatio();
|
|
1507
1987
|
const [width, height] = this.getDrawingBufferSize();
|
|
@@ -1511,10 +1991,10 @@ var _CanvasContext = class {
|
|
|
1511
1991
|
getPixelSize() {
|
|
1512
1992
|
return this.getDevicePixelSize();
|
|
1513
1993
|
}
|
|
1514
|
-
/** @deprecated
|
|
1994
|
+
/** @deprecated Use the current drawing buffer size for projection setup. */
|
|
1515
1995
|
getAspect() {
|
|
1516
|
-
const [width, height] = this.
|
|
1517
|
-
return width / height;
|
|
1996
|
+
const [width, height] = this.getDrawingBufferSize();
|
|
1997
|
+
return width > 0 && height > 0 ? width / height : 1;
|
|
1518
1998
|
}
|
|
1519
1999
|
/** @deprecated Returns multiplier need to convert CSS size to Device size */
|
|
1520
2000
|
cssToDeviceRatio() {
|
|
@@ -1530,19 +2010,41 @@ var _CanvasContext = class {
|
|
|
1530
2010
|
resize(size) {
|
|
1531
2011
|
this.setDrawingBufferSize(size.width, size.height);
|
|
1532
2012
|
}
|
|
1533
|
-
// IMPLEMENTATION
|
|
1534
|
-
/**
|
|
1535
|
-
* Allows subclass constructor to override the canvas id for auto created canvases.
|
|
1536
|
-
* This can really help when debugging DOM in apps that create multiple devices
|
|
1537
|
-
*/
|
|
1538
2013
|
_setAutoCreatedCanvasId(id) {
|
|
1539
2014
|
var _a;
|
|
1540
2015
|
if (((_a = this.htmlCanvas) == null ? void 0 : _a.id) === "lumagl-auto-created-canvas") {
|
|
1541
2016
|
this.htmlCanvas.id = id;
|
|
1542
2017
|
}
|
|
1543
2018
|
}
|
|
1544
|
-
/**
|
|
2019
|
+
/**
|
|
2020
|
+
* Starts DOM observation after the derived context and its device are fully initialized.
|
|
2021
|
+
*
|
|
2022
|
+
* `CanvasSurface` construction runs before subclasses can assign `this.device`, and the
|
|
2023
|
+
* default WebGL canvas context is created before `WebGLDevice` has initialized `limits`,
|
|
2024
|
+
* `features`, and the rest of its runtime state. Deferring observer startup avoids early
|
|
2025
|
+
* `ResizeObserver` and DPR callbacks running against a partially initialized device.
|
|
2026
|
+
*/
|
|
2027
|
+
_startObservers() {
|
|
2028
|
+
if (this.destroyed) {
|
|
2029
|
+
return;
|
|
2030
|
+
}
|
|
2031
|
+
this._canvasObserver.start();
|
|
2032
|
+
}
|
|
2033
|
+
/**
|
|
2034
|
+
* Stops all DOM observation and timers associated with a canvas surface.
|
|
2035
|
+
*
|
|
2036
|
+
* This pairs with `_startObservers()` so teardown uses the same lifecycle whether a context is
|
|
2037
|
+
* explicitly destroyed, abandoned during device reuse, or temporarily has not started observing
|
|
2038
|
+
* yet. Centralizing shutdown here keeps resize/DPR/position watchers from surviving past the
|
|
2039
|
+
* lifetime of the owning device.
|
|
2040
|
+
*/
|
|
2041
|
+
_stopObservers() {
|
|
2042
|
+
this._canvasObserver.stop();
|
|
2043
|
+
}
|
|
1545
2044
|
_handleIntersection(entries) {
|
|
2045
|
+
if (this.destroyed) {
|
|
2046
|
+
return;
|
|
2047
|
+
}
|
|
1546
2048
|
const entry = entries.find((entry_) => entry_.target === this.canvas);
|
|
1547
2049
|
if (!entry) {
|
|
1548
2050
|
return;
|
|
@@ -1553,34 +2055,32 @@ var _CanvasContext = class {
|
|
|
1553
2055
|
this.device.props.onVisibilityChange(this);
|
|
1554
2056
|
}
|
|
1555
2057
|
}
|
|
1556
|
-
/**
|
|
1557
|
-
* Reacts to an observed resize by using the most accurate pixel size information the browser can provide
|
|
1558
|
-
* @see https://web.dev/articles/device-pixel-content-box
|
|
1559
|
-
* @see https://webgpufundamentals.org/webgpu/lessons/webgpu-resizing-the-canvas.html
|
|
1560
|
-
*/
|
|
1561
2058
|
_handleResize(entries) {
|
|
1562
|
-
var _a, _b;
|
|
2059
|
+
var _a, _b, _c, _d, _e;
|
|
2060
|
+
if (this.destroyed) {
|
|
2061
|
+
return;
|
|
2062
|
+
}
|
|
1563
2063
|
const entry = entries.find((entry_) => entry_.target === this.canvas);
|
|
1564
2064
|
if (!entry) {
|
|
1565
2065
|
return;
|
|
1566
2066
|
}
|
|
1567
|
-
|
|
1568
|
-
this.
|
|
2067
|
+
const contentBoxSize = assertDefined((_a = entry.contentBoxSize) == null ? void 0 : _a[0]);
|
|
2068
|
+
this.cssWidth = contentBoxSize.inlineSize;
|
|
2069
|
+
this.cssHeight = contentBoxSize.blockSize;
|
|
1569
2070
|
const oldPixelSize = this.getDevicePixelSize();
|
|
1570
|
-
const devicePixelWidth = ((
|
|
1571
|
-
const devicePixelHeight = ((
|
|
2071
|
+
const devicePixelWidth = ((_c = (_b = entry.devicePixelContentBoxSize) == null ? void 0 : _b[0]) == null ? void 0 : _c.inlineSize) || contentBoxSize.inlineSize * devicePixelRatio;
|
|
2072
|
+
const devicePixelHeight = ((_e = (_d = entry.devicePixelContentBoxSize) == null ? void 0 : _d[0]) == null ? void 0 : _e.blockSize) || contentBoxSize.blockSize * devicePixelRatio;
|
|
1572
2073
|
const [maxDevicePixelWidth, maxDevicePixelHeight] = this.getMaxDrawingBufferSize();
|
|
1573
2074
|
this.devicePixelWidth = Math.max(1, Math.min(devicePixelWidth, maxDevicePixelWidth));
|
|
1574
2075
|
this.devicePixelHeight = Math.max(1, Math.min(devicePixelHeight, maxDevicePixelHeight));
|
|
1575
2076
|
this._updateDrawingBufferSize();
|
|
1576
2077
|
this.device.props.onResize(this, { oldPixelSize });
|
|
1577
2078
|
}
|
|
1578
|
-
/** Initiate a deferred update for the canvas drawing buffer size */
|
|
1579
2079
|
_updateDrawingBufferSize() {
|
|
1580
2080
|
if (this.props.autoResize) {
|
|
1581
2081
|
if (typeof this.props.useDevicePixels === "number") {
|
|
1582
|
-
const
|
|
1583
|
-
this.setDrawingBufferSize(this.cssWidth *
|
|
2082
|
+
const devicePixelRatio2 = this.props.useDevicePixels;
|
|
2083
|
+
this.setDrawingBufferSize(this.cssWidth * devicePixelRatio2, this.cssHeight * devicePixelRatio2);
|
|
1584
2084
|
} else if (this.props.useDevicePixels) {
|
|
1585
2085
|
this.setDrawingBufferSize(this.devicePixelWidth, this.devicePixelHeight);
|
|
1586
2086
|
} else {
|
|
@@ -1591,7 +2091,6 @@ var _CanvasContext = class {
|
|
|
1591
2091
|
this.isInitialized = true;
|
|
1592
2092
|
this.updatePosition();
|
|
1593
2093
|
}
|
|
1594
|
-
/** Perform a deferred resize of the drawing buffer if needed */
|
|
1595
2094
|
_resizeDrawingBufferIfNeeded() {
|
|
1596
2095
|
if (this._needsDrawingBufferResize) {
|
|
1597
2096
|
this._needsDrawingBufferResize = false;
|
|
@@ -1603,31 +2102,23 @@ var _CanvasContext = class {
|
|
|
1603
2102
|
}
|
|
1604
2103
|
}
|
|
1605
2104
|
}
|
|
1606
|
-
/** Monitor DPR changes */
|
|
1607
2105
|
_observeDevicePixelRatio() {
|
|
2106
|
+
var _a, _b;
|
|
2107
|
+
if (this.destroyed || !this._canvasObserver.started) {
|
|
2108
|
+
return;
|
|
2109
|
+
}
|
|
1608
2110
|
const oldRatio = this.devicePixelRatio;
|
|
1609
2111
|
this.devicePixelRatio = window.devicePixelRatio;
|
|
1610
2112
|
this.updatePosition();
|
|
1611
|
-
this.device.props.onDevicePixelRatioChange(this, {
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
/** Start tracking positions with a timer */
|
|
1615
|
-
_trackPosition(intervalMs = 100) {
|
|
1616
|
-
const intervalId = setInterval(() => {
|
|
1617
|
-
if (this.destroyed) {
|
|
1618
|
-
clearInterval(intervalId);
|
|
1619
|
-
} else {
|
|
1620
|
-
this.updatePosition();
|
|
1621
|
-
}
|
|
1622
|
-
}, intervalMs);
|
|
2113
|
+
(_b = (_a = this.device.props).onDevicePixelRatioChange) == null ? void 0 : _b.call(_a, this, {
|
|
2114
|
+
oldRatio
|
|
2115
|
+
});
|
|
1623
2116
|
}
|
|
1624
|
-
/**
|
|
1625
|
-
* Calculated the absolute position of the canvas
|
|
1626
|
-
* @note - getBoundingClientRect() is normally cheap but can be expensive
|
|
1627
|
-
* if called before browser has finished a reflow. Should not be the case here.
|
|
1628
|
-
*/
|
|
1629
2117
|
updatePosition() {
|
|
1630
2118
|
var _a, _b, _c;
|
|
2119
|
+
if (this.destroyed) {
|
|
2120
|
+
return;
|
|
2121
|
+
}
|
|
1631
2122
|
const newRect = (_a = this.htmlCanvas) == null ? void 0 : _a.getBoundingClientRect();
|
|
1632
2123
|
if (newRect) {
|
|
1633
2124
|
const position = [newRect.left, newRect.top];
|
|
@@ -1636,13 +2127,15 @@ var _CanvasContext = class {
|
|
|
1636
2127
|
if (positionChanged) {
|
|
1637
2128
|
const oldPosition = this._position;
|
|
1638
2129
|
this._position = position;
|
|
1639
|
-
(_c = (_b = this.device.props).onPositionChange) == null ? void 0 : _c.call(_b, this, {
|
|
2130
|
+
(_c = (_b = this.device.props).onPositionChange) == null ? void 0 : _c.call(_b, this, {
|
|
2131
|
+
oldPosition
|
|
2132
|
+
});
|
|
1640
2133
|
}
|
|
1641
2134
|
}
|
|
1642
2135
|
}
|
|
1643
2136
|
};
|
|
1644
|
-
var
|
|
1645
|
-
__publicField(
|
|
2137
|
+
var CanvasSurface = _CanvasSurface;
|
|
2138
|
+
__publicField(CanvasSurface, "defaultProps", {
|
|
1646
2139
|
id: void 0,
|
|
1647
2140
|
canvas: null,
|
|
1648
2141
|
width: 800,
|
|
@@ -1670,7 +2163,7 @@ function getContainer(container) {
|
|
|
1670
2163
|
}
|
|
1671
2164
|
function getCanvasFromDOM(canvasId) {
|
|
1672
2165
|
const canvas = document.getElementById(canvasId);
|
|
1673
|
-
if (!
|
|
2166
|
+
if (!CanvasSurface.isHTMLCanvas(canvas)) {
|
|
1674
2167
|
throw new Error("Object is not a canvas element");
|
|
1675
2168
|
}
|
|
1676
2169
|
return canvas;
|
|
@@ -1694,33 +2187,40 @@ function scalePixels(pixel, ratio, width, height, yInvert) {
|
|
|
1694
2187
|
const point = pixel;
|
|
1695
2188
|
const x = scaleX(point[0], ratio, width);
|
|
1696
2189
|
let y = scaleY(point[1], ratio, height, yInvert);
|
|
1697
|
-
let
|
|
1698
|
-
const xHigh =
|
|
1699
|
-
|
|
2190
|
+
let temporary = scaleX(point[0] + 1, ratio, width);
|
|
2191
|
+
const xHigh = temporary === width - 1 ? temporary : temporary - 1;
|
|
2192
|
+
temporary = scaleY(point[1] + 1, ratio, height, yInvert);
|
|
1700
2193
|
let yHigh;
|
|
1701
2194
|
if (yInvert) {
|
|
1702
|
-
|
|
2195
|
+
temporary = temporary === 0 ? temporary : temporary + 1;
|
|
1703
2196
|
yHigh = y;
|
|
1704
|
-
y =
|
|
2197
|
+
y = temporary;
|
|
1705
2198
|
} else {
|
|
1706
|
-
yHigh =
|
|
2199
|
+
yHigh = temporary === height - 1 ? temporary : temporary - 1;
|
|
1707
2200
|
}
|
|
1708
2201
|
return {
|
|
1709
2202
|
x,
|
|
1710
2203
|
y,
|
|
1711
|
-
// when ratio < 1, current css pixel and next css pixel may point to same device pixel, set width/height to 1 in those cases.
|
|
1712
2204
|
width: Math.max(xHigh - x + 1, 1),
|
|
1713
2205
|
height: Math.max(yHigh - y + 1, 1)
|
|
1714
2206
|
};
|
|
1715
2207
|
}
|
|
1716
2208
|
function scaleX(x, ratio, width) {
|
|
1717
|
-
|
|
1718
|
-
return r;
|
|
2209
|
+
return Math.min(Math.round(x * ratio), width - 1);
|
|
1719
2210
|
}
|
|
1720
2211
|
function scaleY(y, ratio, height, yInvert) {
|
|
1721
2212
|
return yInvert ? Math.max(0, height - 1 - Math.round(y * ratio)) : Math.min(Math.round(y * ratio), height - 1);
|
|
1722
2213
|
}
|
|
1723
2214
|
|
|
2215
|
+
// dist/adapter/canvas-context.js
|
|
2216
|
+
var CanvasContext = class extends CanvasSurface {
|
|
2217
|
+
};
|
|
2218
|
+
__publicField(CanvasContext, "defaultProps", CanvasSurface.defaultProps);
|
|
2219
|
+
|
|
2220
|
+
// dist/adapter/presentation-context.js
|
|
2221
|
+
var PresentationContext = class extends CanvasSurface {
|
|
2222
|
+
};
|
|
2223
|
+
|
|
1724
2224
|
// dist/adapter/resources/sampler.js
|
|
1725
2225
|
var _Sampler = class extends Resource {
|
|
1726
2226
|
get [Symbol.toStringTag]() {
|
|
@@ -1775,6 +2275,8 @@ var _Texture = class extends Resource {
|
|
|
1775
2275
|
depth;
|
|
1776
2276
|
/** mip levels in this texture */
|
|
1777
2277
|
mipLevels;
|
|
2278
|
+
/** sample count */
|
|
2279
|
+
samples;
|
|
1778
2280
|
/** Rows are multiples of this length, padded with extra bytes if needed */
|
|
1779
2281
|
byteAlignment;
|
|
1780
2282
|
/** The ready promise is always resolved. It is provided for type compatibility with DynamicTexture. */
|
|
@@ -1800,6 +2302,7 @@ var _Texture = class extends Resource {
|
|
|
1800
2302
|
this.height = this.props.height;
|
|
1801
2303
|
this.depth = this.props.depth;
|
|
1802
2304
|
this.mipLevels = this.props.mipLevels;
|
|
2305
|
+
this.samples = this.props.samples || 1;
|
|
1803
2306
|
if (this.dimension === "cube") {
|
|
1804
2307
|
this.depth = 6;
|
|
1805
2308
|
}
|
|
@@ -1831,9 +2334,25 @@ var _Texture = class extends Resource {
|
|
|
1831
2334
|
setSampler(sampler) {
|
|
1832
2335
|
this.sampler = sampler instanceof Sampler ? sampler : this.device.createSampler(sampler);
|
|
1833
2336
|
}
|
|
2337
|
+
/**
|
|
2338
|
+
* Copy raw image data (bytes) into the texture.
|
|
2339
|
+
*
|
|
2340
|
+
* @note Deprecated compatibility wrapper over {@link writeData}.
|
|
2341
|
+
* @note Uses the same layout defaults and alignment rules as {@link writeData}.
|
|
2342
|
+
* @note Tightly packed CPU uploads can omit `bytesPerRow` and `rowsPerImage`.
|
|
2343
|
+
* @note If the CPU source rows are padded, pass explicit `bytesPerRow` and `rowsPerImage`.
|
|
2344
|
+
* @deprecated Use writeData()
|
|
2345
|
+
*/
|
|
2346
|
+
copyImageData(options) {
|
|
2347
|
+
const { data, depth, ...writeOptions } = options;
|
|
2348
|
+
this.writeData(data, {
|
|
2349
|
+
...writeOptions,
|
|
2350
|
+
depthOrArrayLayers: writeOptions.depthOrArrayLayers ?? depth
|
|
2351
|
+
});
|
|
2352
|
+
}
|
|
1834
2353
|
/**
|
|
1835
2354
|
* Calculates the memory layout of the texture, required when reading and writing data.
|
|
1836
|
-
* @return the
|
|
2355
|
+
* @return the backend-aligned linear layout, in particular bytesPerRow which includes any required padding for buffer copy/read paths
|
|
1837
2356
|
*/
|
|
1838
2357
|
computeMemoryLayout(options_ = {}) {
|
|
1839
2358
|
const options = this._normalizeTextureReadOptions(options_);
|
|
@@ -1852,9 +2371,11 @@ var _Texture = class extends Resource {
|
|
|
1852
2371
|
* @returns A Buffer containing the texture data.
|
|
1853
2372
|
*
|
|
1854
2373
|
* @note The memory layout of the texture data is determined by the texture format and dimensions.
|
|
1855
|
-
* @note The application can call Texture.computeMemoryLayout() to compute the layout.
|
|
2374
|
+
* @note The application can call Texture.computeMemoryLayout() to compute the backend-aligned layout.
|
|
1856
2375
|
* @note The application can call Buffer.readAsync()
|
|
1857
2376
|
* @note If not supplied a buffer will be created and the application needs to call Buffer.destroy
|
|
2377
|
+
* @note On WebGPU this corresponds to a texture-to-buffer copy and uses buffer-copy alignment rules.
|
|
2378
|
+
* @note On WebGL, luma.gl emulates the same logical readback behavior.
|
|
1858
2379
|
*/
|
|
1859
2380
|
readBuffer(options, buffer) {
|
|
1860
2381
|
throw new Error("readBuffer not implemented");
|
|
@@ -1870,10 +2391,14 @@ var _Texture = class extends Resource {
|
|
|
1870
2391
|
throw new Error("readBuffer not implemented");
|
|
1871
2392
|
}
|
|
1872
2393
|
/**
|
|
1873
|
-
* Writes
|
|
2394
|
+
* Writes a GPU Buffer into a texture.
|
|
1874
2395
|
*
|
|
2396
|
+
* @param buffer - Source GPU buffer.
|
|
2397
|
+
* @param options - Destination subresource, extent, and source layout options.
|
|
1875
2398
|
* @note The memory layout of the texture data is determined by the texture format and dimensions.
|
|
1876
|
-
* @note The application can call Texture.computeMemoryLayout() to compute the layout.
|
|
2399
|
+
* @note The application can call Texture.computeMemoryLayout() to compute the backend-aligned layout.
|
|
2400
|
+
* @note On WebGPU this corresponds to a buffer-to-texture copy and uses buffer-copy alignment rules.
|
|
2401
|
+
* @note On WebGL, luma.gl emulates the same destination and layout semantics.
|
|
1877
2402
|
*/
|
|
1878
2403
|
writeBuffer(buffer, options) {
|
|
1879
2404
|
throw new Error("readBuffer not implemented");
|
|
@@ -1881,8 +2406,11 @@ var _Texture = class extends Resource {
|
|
|
1881
2406
|
/**
|
|
1882
2407
|
* Writes an array buffer into a texture.
|
|
1883
2408
|
*
|
|
1884
|
-
* @
|
|
1885
|
-
* @
|
|
2409
|
+
* @param data - Source texel data.
|
|
2410
|
+
* @param options - Destination subresource, extent, and source layout options.
|
|
2411
|
+
* @note If `bytesPerRow` and `rowsPerImage` are omitted, luma.gl computes a tightly packed CPU-memory layout for the requested region.
|
|
2412
|
+
* @note On WebGPU this corresponds to `GPUQueue.writeTexture()` and does not implicitly pad rows to 256 bytes.
|
|
2413
|
+
* @note On WebGL, padded CPU data is supported via the same `bytesPerRow` and `rowsPerImage` options.
|
|
1886
2414
|
*/
|
|
1887
2415
|
writeData(data, options) {
|
|
1888
2416
|
throw new Error("readBuffer not implemented");
|
|
@@ -1945,37 +2473,148 @@ var _Texture = class extends Resource {
|
|
|
1945
2473
|
}
|
|
1946
2474
|
}
|
|
1947
2475
|
_normalizeCopyImageDataOptions(options_) {
|
|
1948
|
-
const {
|
|
1949
|
-
const options = {
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
}
|
|
1954
|
-
options.bytesPerRow = options_.bytesPerRow || width * (info.bytesPerPixel || 4);
|
|
1955
|
-
options.rowsPerImage = options_.rowsPerImage || height;
|
|
1956
|
-
return options;
|
|
2476
|
+
const { data, depth, ...writeOptions } = options_;
|
|
2477
|
+
const options = this._normalizeTextureWriteOptions({
|
|
2478
|
+
...writeOptions,
|
|
2479
|
+
depthOrArrayLayers: writeOptions.depthOrArrayLayers ?? depth
|
|
2480
|
+
});
|
|
2481
|
+
return { data, depth: options.depthOrArrayLayers, ...options };
|
|
1957
2482
|
}
|
|
1958
2483
|
_normalizeCopyExternalImageOptions(options_) {
|
|
2484
|
+
const optionsWithoutUndefined = _Texture._omitUndefined(options_);
|
|
2485
|
+
const mipLevel = optionsWithoutUndefined.mipLevel ?? 0;
|
|
2486
|
+
const mipLevelSize = this._getMipLevelSize(mipLevel);
|
|
1959
2487
|
const size = this.device.getExternalImageSize(options_.image);
|
|
1960
|
-
const options = {
|
|
1961
|
-
|
|
1962
|
-
|
|
2488
|
+
const options = {
|
|
2489
|
+
..._Texture.defaultCopyExternalImageOptions,
|
|
2490
|
+
...mipLevelSize,
|
|
2491
|
+
...size,
|
|
2492
|
+
...optionsWithoutUndefined
|
|
2493
|
+
};
|
|
2494
|
+
options.width = Math.min(options.width, mipLevelSize.width - options.x);
|
|
2495
|
+
options.height = Math.min(options.height, mipLevelSize.height - options.y);
|
|
2496
|
+
options.depth = Math.min(options.depth, mipLevelSize.depthOrArrayLayers - options.z);
|
|
1963
2497
|
return options;
|
|
1964
2498
|
}
|
|
1965
2499
|
_normalizeTextureReadOptions(options_) {
|
|
1966
|
-
const
|
|
1967
|
-
const
|
|
1968
|
-
|
|
1969
|
-
options
|
|
2500
|
+
const optionsWithoutUndefined = _Texture._omitUndefined(options_);
|
|
2501
|
+
const mipLevel = optionsWithoutUndefined.mipLevel ?? 0;
|
|
2502
|
+
const mipLevelSize = this._getMipLevelSize(mipLevel);
|
|
2503
|
+
const options = {
|
|
2504
|
+
..._Texture.defaultTextureReadOptions,
|
|
2505
|
+
...mipLevelSize,
|
|
2506
|
+
...optionsWithoutUndefined
|
|
2507
|
+
};
|
|
2508
|
+
options.width = Math.min(options.width, mipLevelSize.width - options.x);
|
|
2509
|
+
options.height = Math.min(options.height, mipLevelSize.height - options.y);
|
|
2510
|
+
options.depthOrArrayLayers = Math.min(options.depthOrArrayLayers, mipLevelSize.depthOrArrayLayers - options.z);
|
|
1970
2511
|
return options;
|
|
1971
2512
|
}
|
|
2513
|
+
/**
|
|
2514
|
+
* Normalizes a texture read request and validates the color-only readback contract used by the
|
|
2515
|
+
* current texture read APIs. Supported dimensions are `2d`, `cube`, `cube-array`,
|
|
2516
|
+
* `2d-array`, and `3d`.
|
|
2517
|
+
*
|
|
2518
|
+
* @throws if the texture format, aspect, or dimension is not supported by the first-pass
|
|
2519
|
+
* color-read implementation.
|
|
2520
|
+
*/
|
|
2521
|
+
_getSupportedColorReadOptions(options_) {
|
|
2522
|
+
const options = this._normalizeTextureReadOptions(options_);
|
|
2523
|
+
const formatInfo = textureFormatDecoder.getInfo(this.format);
|
|
2524
|
+
this._validateColorReadAspect(options);
|
|
2525
|
+
this._validateColorReadFormat(formatInfo);
|
|
2526
|
+
switch (this.dimension) {
|
|
2527
|
+
case "2d":
|
|
2528
|
+
case "cube":
|
|
2529
|
+
case "cube-array":
|
|
2530
|
+
case "2d-array":
|
|
2531
|
+
case "3d":
|
|
2532
|
+
return options;
|
|
2533
|
+
default:
|
|
2534
|
+
throw new Error(`${this} color readback does not support ${this.dimension} textures`);
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
/** Validates that a read request targets the full color aspect of the texture. */
|
|
2538
|
+
_validateColorReadAspect(options) {
|
|
2539
|
+
if (options.aspect !== "all") {
|
|
2540
|
+
throw new Error(`${this} color readback only supports aspect 'all'`);
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
/** Validates that a read request targets an uncompressed color-renderable texture format. */
|
|
2544
|
+
_validateColorReadFormat(formatInfo) {
|
|
2545
|
+
if (formatInfo.compressed) {
|
|
2546
|
+
throw new Error(`${this} color readback does not support compressed formats (${this.format})`);
|
|
2547
|
+
}
|
|
2548
|
+
switch (formatInfo.attachment) {
|
|
2549
|
+
case "color":
|
|
2550
|
+
return;
|
|
2551
|
+
case "depth":
|
|
2552
|
+
throw new Error(`${this} color readback does not support depth formats (${this.format})`);
|
|
2553
|
+
case "stencil":
|
|
2554
|
+
throw new Error(`${this} color readback does not support stencil formats (${this.format})`);
|
|
2555
|
+
case "depth-stencil":
|
|
2556
|
+
throw new Error(`${this} color readback does not support depth-stencil formats (${this.format})`);
|
|
2557
|
+
default:
|
|
2558
|
+
throw new Error(`${this} color readback does not support format ${this.format}`);
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
1972
2561
|
_normalizeTextureWriteOptions(options_) {
|
|
1973
|
-
const
|
|
1974
|
-
const
|
|
1975
|
-
|
|
1976
|
-
options
|
|
2562
|
+
const optionsWithoutUndefined = _Texture._omitUndefined(options_);
|
|
2563
|
+
const mipLevel = optionsWithoutUndefined.mipLevel ?? 0;
|
|
2564
|
+
const mipLevelSize = this._getMipLevelSize(mipLevel);
|
|
2565
|
+
const options = {
|
|
2566
|
+
..._Texture.defaultTextureWriteOptions,
|
|
2567
|
+
...mipLevelSize,
|
|
2568
|
+
...optionsWithoutUndefined
|
|
2569
|
+
};
|
|
2570
|
+
options.width = Math.min(options.width, mipLevelSize.width - options.x);
|
|
2571
|
+
options.height = Math.min(options.height, mipLevelSize.height - options.y);
|
|
2572
|
+
options.depthOrArrayLayers = Math.min(options.depthOrArrayLayers, mipLevelSize.depthOrArrayLayers - options.z);
|
|
2573
|
+
const layout = textureFormatDecoder.computeMemoryLayout({
|
|
2574
|
+
format: this.format,
|
|
2575
|
+
width: options.width,
|
|
2576
|
+
height: options.height,
|
|
2577
|
+
depth: options.depthOrArrayLayers,
|
|
2578
|
+
byteAlignment: this.byteAlignment
|
|
2579
|
+
});
|
|
2580
|
+
const minimumBytesPerRow = layout.bytesPerPixel * options.width;
|
|
2581
|
+
options.bytesPerRow = optionsWithoutUndefined.bytesPerRow ?? layout.bytesPerRow;
|
|
2582
|
+
options.rowsPerImage = optionsWithoutUndefined.rowsPerImage ?? options.height;
|
|
2583
|
+
if (options.bytesPerRow < minimumBytesPerRow) {
|
|
2584
|
+
throw new Error(`bytesPerRow (${options.bytesPerRow}) must be at least ${minimumBytesPerRow} for ${this.format}`);
|
|
2585
|
+
}
|
|
2586
|
+
if (options.rowsPerImage < options.height) {
|
|
2587
|
+
throw new Error(`rowsPerImage (${options.rowsPerImage}) must be at least ${options.height} for ${this.format}`);
|
|
2588
|
+
}
|
|
2589
|
+
const bytesPerPixel = this.device.getTextureFormatInfo(this.format).bytesPerPixel;
|
|
2590
|
+
if (bytesPerPixel && options.bytesPerRow % bytesPerPixel !== 0) {
|
|
2591
|
+
throw new Error(`bytesPerRow (${options.bytesPerRow}) must be a multiple of bytesPerPixel (${bytesPerPixel}) for ${this.format}`);
|
|
2592
|
+
}
|
|
1977
2593
|
return options;
|
|
1978
2594
|
}
|
|
2595
|
+
_getMipLevelSize(mipLevel) {
|
|
2596
|
+
const width = Math.max(1, this.width >> mipLevel);
|
|
2597
|
+
const height = this.baseDimension === "1d" ? 1 : Math.max(1, this.height >> mipLevel);
|
|
2598
|
+
const depthOrArrayLayers = this.dimension === "3d" ? Math.max(1, this.depth >> mipLevel) : this.depth;
|
|
2599
|
+
return { width, height, depthOrArrayLayers };
|
|
2600
|
+
}
|
|
2601
|
+
getAllocatedByteLength() {
|
|
2602
|
+
let allocatedByteLength = 0;
|
|
2603
|
+
for (let mipLevel = 0; mipLevel < this.mipLevels; mipLevel++) {
|
|
2604
|
+
const { width, height, depthOrArrayLayers } = this._getMipLevelSize(mipLevel);
|
|
2605
|
+
allocatedByteLength += textureFormatDecoder.computeMemoryLayout({
|
|
2606
|
+
format: this.format,
|
|
2607
|
+
width,
|
|
2608
|
+
height,
|
|
2609
|
+
depth: depthOrArrayLayers,
|
|
2610
|
+
byteAlignment: 1
|
|
2611
|
+
}).byteLength;
|
|
2612
|
+
}
|
|
2613
|
+
return allocatedByteLength * this.samples;
|
|
2614
|
+
}
|
|
2615
|
+
static _omitUndefined(options) {
|
|
2616
|
+
return Object.fromEntries(Object.entries(options).filter(([, value]) => value !== void 0));
|
|
2617
|
+
}
|
|
1979
2618
|
};
|
|
1980
2619
|
var Texture = _Texture;
|
|
1981
2620
|
/** The texture can be bound for use as a sampled texture in a shader */
|
|
@@ -2011,6 +2650,10 @@ __publicField(Texture, "defaultCopyDataOptions", {
|
|
|
2011
2650
|
byteOffset: 0,
|
|
2012
2651
|
bytesPerRow: void 0,
|
|
2013
2652
|
rowsPerImage: void 0,
|
|
2653
|
+
width: void 0,
|
|
2654
|
+
height: void 0,
|
|
2655
|
+
depthOrArrayLayers: void 0,
|
|
2656
|
+
depth: 1,
|
|
2014
2657
|
mipLevel: 0,
|
|
2015
2658
|
x: 0,
|
|
2016
2659
|
y: 0,
|
|
@@ -2044,6 +2687,19 @@ __publicField(Texture, "defaultTextureReadOptions", {
|
|
|
2044
2687
|
mipLevel: 0,
|
|
2045
2688
|
aspect: "all"
|
|
2046
2689
|
});
|
|
2690
|
+
__publicField(Texture, "defaultTextureWriteOptions", {
|
|
2691
|
+
byteOffset: 0,
|
|
2692
|
+
bytesPerRow: void 0,
|
|
2693
|
+
rowsPerImage: void 0,
|
|
2694
|
+
x: 0,
|
|
2695
|
+
y: 0,
|
|
2696
|
+
z: 0,
|
|
2697
|
+
width: void 0,
|
|
2698
|
+
height: void 0,
|
|
2699
|
+
depthOrArrayLayers: 1,
|
|
2700
|
+
mipLevel: 0,
|
|
2701
|
+
aspect: "all"
|
|
2702
|
+
});
|
|
2047
2703
|
|
|
2048
2704
|
// dist/adapter/resources/texture-view.js
|
|
2049
2705
|
var _TextureView = class extends Resource {
|
|
@@ -2090,24 +2746,32 @@ function formatCompilerLog(shaderLog, source, options) {
|
|
|
2090
2746
|
const log2 = shaderLog.slice().sort((a, b) => a.lineNum - b.lineNum);
|
|
2091
2747
|
switch ((options == null ? void 0 : options.showSourceCode) || "no") {
|
|
2092
2748
|
case "all":
|
|
2093
|
-
let
|
|
2749
|
+
let currentMessageIndex = 0;
|
|
2094
2750
|
for (let lineNum = 1; lineNum <= lines.length; lineNum++) {
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
formattedLog +=
|
|
2751
|
+
const line = lines[lineNum - 1];
|
|
2752
|
+
const currentMessage = log2[currentMessageIndex];
|
|
2753
|
+
if (line && currentMessage) {
|
|
2754
|
+
formattedLog += getNumberedLine(line, lineNum, options);
|
|
2755
|
+
}
|
|
2756
|
+
while (log2.length > currentMessageIndex && currentMessage.lineNum === lineNum) {
|
|
2757
|
+
const message = log2[currentMessageIndex++];
|
|
2758
|
+
if (message) {
|
|
2759
|
+
formattedLog += formatCompilerMessage(message, lines, message.lineNum, {
|
|
2760
|
+
...options,
|
|
2761
|
+
inlineSource: false
|
|
2762
|
+
});
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2765
|
+
}
|
|
2766
|
+
while (log2.length > currentMessageIndex) {
|
|
2767
|
+
const message = log2[currentMessageIndex++];
|
|
2768
|
+
if (message) {
|
|
2769
|
+
formattedLog += formatCompilerMessage(message, [], 0, {
|
|
2099
2770
|
...options,
|
|
2100
2771
|
inlineSource: false
|
|
2101
2772
|
});
|
|
2102
2773
|
}
|
|
2103
2774
|
}
|
|
2104
|
-
while (log2.length > currentMessage) {
|
|
2105
|
-
const message = log2[currentMessage++];
|
|
2106
|
-
formattedLog += formatCompilerMessage(message, [], 0, {
|
|
2107
|
-
...options,
|
|
2108
|
-
inlineSource: false
|
|
2109
|
-
});
|
|
2110
|
-
}
|
|
2111
2775
|
return formattedLog;
|
|
2112
2776
|
case "issues":
|
|
2113
2777
|
case "no":
|
|
@@ -2129,8 +2793,8 @@ ${numberedLines}${positionIndicator}${message.type.toUpperCase()}: ${message.mes
|
|
|
2129
2793
|
|
|
2130
2794
|
`;
|
|
2131
2795
|
}
|
|
2132
|
-
const color = message.type === "error" ? "red" : "
|
|
2133
|
-
return (options == null ? void 0 : options.html) ? `<div class='luma-compiler-log
|
|
2796
|
+
const color = message.type === "error" ? "red" : "orange";
|
|
2797
|
+
return (options == null ? void 0 : 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}`;
|
|
2134
2798
|
}
|
|
2135
2799
|
function getNumberedLines(lines, lineNum, options) {
|
|
2136
2800
|
let numberedLines = "";
|
|
@@ -2211,35 +2875,39 @@ var _Shader = class extends Resource {
|
|
|
2211
2875
|
* TODO - this HTML formatting code should not be in Device, should be pluggable
|
|
2212
2876
|
*/
|
|
2213
2877
|
_displayShaderLog(messages, shaderId) {
|
|
2214
|
-
var _a;
|
|
2215
2878
|
if (typeof document === "undefined" || !(document == null ? void 0 : document.createElement)) {
|
|
2216
2879
|
return;
|
|
2217
2880
|
}
|
|
2218
2881
|
const shaderName = shaderId;
|
|
2219
2882
|
const shaderTitle = `${this.stage} shader "${shaderName}"`;
|
|
2220
|
-
|
|
2883
|
+
const htmlLog = formatCompilerLog(messages, this.source, { showSourceCode: "all", html: true });
|
|
2221
2884
|
const translatedSource = this.getTranslatedSource();
|
|
2885
|
+
const container = document.createElement("div");
|
|
2886
|
+
container.innerHTML = `<h1>Compilation error in ${shaderTitle}</h1>
|
|
2887
|
+
<div style="display:flex;position:fixed;top:10px;right:20px;gap:2px;">
|
|
2888
|
+
<button id="copy">Copy source</button><br/>
|
|
2889
|
+
<button id="close">Close</button>
|
|
2890
|
+
</div>
|
|
2891
|
+
<code><pre>${htmlLog}</pre></code>`;
|
|
2222
2892
|
if (translatedSource) {
|
|
2223
|
-
|
|
2224
|
-
}
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
button.
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
(
|
|
2240
|
-
|
|
2241
|
-
const dataURI = `data:text/plain,${encodeURIComponent(this.source)}`;
|
|
2242
|
-
navigator.clipboard.writeText(dataURI);
|
|
2893
|
+
container.innerHTML += `<br /><h1>Translated Source</h1><br /><br /><code><pre>${translatedSource}</pre></code>`;
|
|
2894
|
+
}
|
|
2895
|
+
container.style.top = "0";
|
|
2896
|
+
container.style.left = "0";
|
|
2897
|
+
container.style.background = "white";
|
|
2898
|
+
container.style.position = "fixed";
|
|
2899
|
+
container.style.zIndex = "9999";
|
|
2900
|
+
container.style.maxWidth = "100vw";
|
|
2901
|
+
container.style.maxHeight = "100vh";
|
|
2902
|
+
container.style.overflowY = "auto";
|
|
2903
|
+
document.body.appendChild(container);
|
|
2904
|
+
const error = container.querySelector(".luma-compiler-log-error");
|
|
2905
|
+
error == null ? void 0 : error.scrollIntoView();
|
|
2906
|
+
container.querySelector("button#close").onclick = () => {
|
|
2907
|
+
container.remove();
|
|
2908
|
+
};
|
|
2909
|
+
container.querySelector("button#copy").onclick = () => {
|
|
2910
|
+
navigator.clipboard.writeText(this.source);
|
|
2243
2911
|
};
|
|
2244
2912
|
}
|
|
2245
2913
|
};
|
|
@@ -2259,7 +2927,7 @@ function getShaderIdFromProps(props) {
|
|
|
2259
2927
|
function getShaderName(shader, defaultName = "unnamed") {
|
|
2260
2928
|
const SHADER_NAME_REGEXP = /#define[\s*]SHADER_NAME[\s*]([A-Za-z0-9_-]+)[\s*]/;
|
|
2261
2929
|
const match = SHADER_NAME_REGEXP.exec(shader);
|
|
2262
|
-
return match ? match[1]
|
|
2930
|
+
return (match == null ? void 0 : match[1]) ?? defaultName;
|
|
2263
2931
|
}
|
|
2264
2932
|
|
|
2265
2933
|
// dist/adapter/resources/framebuffer.js
|
|
@@ -2363,17 +3031,15 @@ var _Framebuffer = class extends Resource {
|
|
|
2363
3031
|
* and destroys existing textures if owned
|
|
2364
3032
|
*/
|
|
2365
3033
|
resizeAttachments(width, height) {
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
}
|
|
2376
|
-
}
|
|
3034
|
+
this.colorAttachments.forEach((colorAttachment, i) => {
|
|
3035
|
+
const resizedTexture = colorAttachment.texture.clone({
|
|
3036
|
+
width,
|
|
3037
|
+
height
|
|
3038
|
+
});
|
|
3039
|
+
this.destroyAttachedResource(colorAttachment);
|
|
3040
|
+
this.colorAttachments[i] = resizedTexture.view;
|
|
3041
|
+
this.attachResource(resizedTexture.view);
|
|
3042
|
+
});
|
|
2377
3043
|
if (this.depthStencilAttachment) {
|
|
2378
3044
|
const resizedTexture = this.depthStencilAttachment.texture.clone({
|
|
2379
3045
|
width,
|
|
@@ -2410,10 +3076,23 @@ var _RenderPipeline = class extends Resource {
|
|
|
2410
3076
|
linkStatus = "pending";
|
|
2411
3077
|
/** The hash of the pipeline */
|
|
2412
3078
|
hash = "";
|
|
3079
|
+
/** Optional shared backend implementation */
|
|
3080
|
+
sharedRenderPipeline = null;
|
|
3081
|
+
/** Whether shader or pipeline compilation/linking is still in progress */
|
|
3082
|
+
get isPending() {
|
|
3083
|
+
var _a;
|
|
3084
|
+
return this.linkStatus === "pending" || this.vs.compilationStatus === "pending" || ((_a = this.fs) == null ? void 0 : _a.compilationStatus) === "pending";
|
|
3085
|
+
}
|
|
3086
|
+
/** Whether shader or pipeline compilation/linking has failed */
|
|
3087
|
+
get isErrored() {
|
|
3088
|
+
var _a;
|
|
3089
|
+
return this.linkStatus === "error" || this.vs.compilationStatus === "error" || ((_a = this.fs) == null ? void 0 : _a.compilationStatus) === "error";
|
|
3090
|
+
}
|
|
2413
3091
|
constructor(device, props) {
|
|
2414
3092
|
super(device, props, _RenderPipeline.defaultProps);
|
|
2415
3093
|
this.shaderLayout = this.props.shaderLayout;
|
|
2416
3094
|
this.bufferLayout = this.props.bufferLayout || [];
|
|
3095
|
+
this.sharedRenderPipeline = this.props._sharedRenderPipeline || null;
|
|
2417
3096
|
}
|
|
2418
3097
|
};
|
|
2419
3098
|
var RenderPipeline = _RenderPipeline;
|
|
@@ -2431,10 +3110,30 @@ __publicField(RenderPipeline, "defaultProps", {
|
|
|
2431
3110
|
colorAttachmentFormats: void 0,
|
|
2432
3111
|
depthStencilAttachmentFormat: void 0,
|
|
2433
3112
|
parameters: {},
|
|
2434
|
-
|
|
2435
|
-
|
|
3113
|
+
varyings: void 0,
|
|
3114
|
+
bufferMode: void 0,
|
|
3115
|
+
disableWarnings: false,
|
|
3116
|
+
_sharedRenderPipeline: void 0,
|
|
3117
|
+
bindings: void 0
|
|
2436
3118
|
});
|
|
2437
3119
|
|
|
3120
|
+
// dist/adapter/resources/shared-render-pipeline.js
|
|
3121
|
+
var SharedRenderPipeline = class extends Resource {
|
|
3122
|
+
get [Symbol.toStringTag]() {
|
|
3123
|
+
return "SharedRenderPipeline";
|
|
3124
|
+
}
|
|
3125
|
+
constructor(device, props) {
|
|
3126
|
+
super(device, props, {
|
|
3127
|
+
...Resource.defaultProps,
|
|
3128
|
+
handle: void 0,
|
|
3129
|
+
vs: void 0,
|
|
3130
|
+
fs: void 0,
|
|
3131
|
+
varyings: void 0,
|
|
3132
|
+
bufferMode: void 0
|
|
3133
|
+
});
|
|
3134
|
+
}
|
|
3135
|
+
};
|
|
3136
|
+
|
|
2438
3137
|
// dist/adapter/resources/render-pass.js
|
|
2439
3138
|
var _RenderPass = class extends Resource {
|
|
2440
3139
|
get [Symbol.toStringTag]() {
|
|
@@ -2517,8 +3216,69 @@ var _CommandEncoder = class extends Resource {
|
|
|
2517
3216
|
get [Symbol.toStringTag]() {
|
|
2518
3217
|
return "CommandEncoder";
|
|
2519
3218
|
}
|
|
3219
|
+
_timeProfilingQuerySet = null;
|
|
3220
|
+
_timeProfilingSlotCount = 0;
|
|
3221
|
+
_gpuTimeMs;
|
|
2520
3222
|
constructor(device, props) {
|
|
2521
3223
|
super(device, props, _CommandEncoder.defaultProps);
|
|
3224
|
+
this._timeProfilingQuerySet = props.timeProfilingQuerySet ?? null;
|
|
3225
|
+
this._timeProfilingSlotCount = 0;
|
|
3226
|
+
this._gpuTimeMs = void 0;
|
|
3227
|
+
}
|
|
3228
|
+
/**
|
|
3229
|
+
* Reads all resolved timestamp pairs on the current profiler query set and caches the sum
|
|
3230
|
+
* as milliseconds on this encoder.
|
|
3231
|
+
*/
|
|
3232
|
+
async resolveTimeProfilingQuerySet() {
|
|
3233
|
+
this._gpuTimeMs = void 0;
|
|
3234
|
+
if (!this._timeProfilingQuerySet) {
|
|
3235
|
+
return;
|
|
3236
|
+
}
|
|
3237
|
+
const pairCount = Math.floor(this._timeProfilingSlotCount / 2);
|
|
3238
|
+
if (pairCount <= 0) {
|
|
3239
|
+
return;
|
|
3240
|
+
}
|
|
3241
|
+
const queryCount = pairCount * 2;
|
|
3242
|
+
const results = await this._timeProfilingQuerySet.readResults({
|
|
3243
|
+
firstQuery: 0,
|
|
3244
|
+
queryCount
|
|
3245
|
+
});
|
|
3246
|
+
let totalDurationNanoseconds = 0n;
|
|
3247
|
+
for (let queryIndex = 0; queryIndex < queryCount; queryIndex += 2) {
|
|
3248
|
+
totalDurationNanoseconds += results[queryIndex + 1] - results[queryIndex];
|
|
3249
|
+
}
|
|
3250
|
+
this._gpuTimeMs = Number(totalDurationNanoseconds) / 1e6;
|
|
3251
|
+
}
|
|
3252
|
+
/** Returns the number of query slots consumed by automatic pass profiling on this encoder. */
|
|
3253
|
+
getTimeProfilingSlotCount() {
|
|
3254
|
+
return this._timeProfilingSlotCount;
|
|
3255
|
+
}
|
|
3256
|
+
getTimeProfilingQuerySet() {
|
|
3257
|
+
return this._timeProfilingQuerySet;
|
|
3258
|
+
}
|
|
3259
|
+
/** Internal helper for auto-assigning timestamp slots to render/compute passes on this encoder. */
|
|
3260
|
+
_applyTimeProfilingToPassProps(props) {
|
|
3261
|
+
const passProps = props || {};
|
|
3262
|
+
if (!this._supportsTimestampQueries() || !this._timeProfilingQuerySet) {
|
|
3263
|
+
return passProps;
|
|
3264
|
+
}
|
|
3265
|
+
if (passProps.timestampQuerySet !== void 0 || passProps.beginTimestampIndex !== void 0 || passProps.endTimestampIndex !== void 0) {
|
|
3266
|
+
return passProps;
|
|
3267
|
+
}
|
|
3268
|
+
const beginTimestampIndex = this._timeProfilingSlotCount;
|
|
3269
|
+
if (beginTimestampIndex + 1 >= this._timeProfilingQuerySet.props.count) {
|
|
3270
|
+
return passProps;
|
|
3271
|
+
}
|
|
3272
|
+
this._timeProfilingSlotCount += 2;
|
|
3273
|
+
return {
|
|
3274
|
+
...passProps,
|
|
3275
|
+
timestampQuerySet: this._timeProfilingQuerySet,
|
|
3276
|
+
beginTimestampIndex,
|
|
3277
|
+
endTimestampIndex: beginTimestampIndex + 1
|
|
3278
|
+
};
|
|
3279
|
+
}
|
|
3280
|
+
_supportsTimestampQueries() {
|
|
3281
|
+
return this.device.features.has("timestamp-query");
|
|
2522
3282
|
}
|
|
2523
3283
|
};
|
|
2524
3284
|
var CommandEncoder = _CommandEncoder;
|
|
@@ -2527,7 +3287,8 @@ var CommandEncoder = _CommandEncoder;
|
|
|
2527
3287
|
// beginComputePass(optional GPUComputePassDescriptor descriptor = {}): GPUComputePassEncoder;
|
|
2528
3288
|
__publicField(CommandEncoder, "defaultProps", {
|
|
2529
3289
|
...Resource.defaultProps,
|
|
2530
|
-
measureExecutionTime: void 0
|
|
3290
|
+
measureExecutionTime: void 0,
|
|
3291
|
+
timeProfilingQuerySet: void 0
|
|
2531
3292
|
});
|
|
2532
3293
|
|
|
2533
3294
|
// dist/adapter/resources/command-buffer.js
|
|
@@ -2546,11 +3307,20 @@ __publicField(CommandBuffer, "defaultProps", {
|
|
|
2546
3307
|
|
|
2547
3308
|
// dist/shadertypes/data-types/decode-shader-types.js
|
|
2548
3309
|
function getVariableShaderTypeInfo(format) {
|
|
2549
|
-
const
|
|
3310
|
+
const resolvedFormat = resolveVariableShaderTypeAlias(format);
|
|
3311
|
+
const decoded = UNIFORM_FORMATS[resolvedFormat];
|
|
3312
|
+
if (!decoded) {
|
|
3313
|
+
throw new Error(`Unsupported variable shader type: ${format}`);
|
|
3314
|
+
}
|
|
2550
3315
|
return decoded;
|
|
2551
3316
|
}
|
|
2552
3317
|
function getAttributeShaderTypeInfo(attributeType) {
|
|
2553
|
-
const
|
|
3318
|
+
const resolvedAttributeType = resolveAttributeShaderTypeAlias(attributeType);
|
|
3319
|
+
const decoded = TYPE_INFO[resolvedAttributeType];
|
|
3320
|
+
if (!decoded) {
|
|
3321
|
+
throw new Error(`Unsupported attribute shader type: ${attributeType}`);
|
|
3322
|
+
}
|
|
3323
|
+
const [primitiveType, components] = decoded;
|
|
2554
3324
|
const integer = primitiveType === "i32" || primitiveType === "u32";
|
|
2555
3325
|
const signed = primitiveType !== "u32";
|
|
2556
3326
|
const byteLength = PRIMITIVE_TYPE_SIZES[primitiveType] * components;
|
|
@@ -2562,6 +3332,12 @@ function getAttributeShaderTypeInfo(attributeType) {
|
|
|
2562
3332
|
signed
|
|
2563
3333
|
};
|
|
2564
3334
|
}
|
|
3335
|
+
function resolveAttributeShaderTypeAlias(alias) {
|
|
3336
|
+
return WGSL_ATTRIBUTE_TYPE_ALIAS_MAP[alias] || alias;
|
|
3337
|
+
}
|
|
3338
|
+
function resolveVariableShaderTypeAlias(alias) {
|
|
3339
|
+
return WGSL_VARIABLE_TYPE_ALIAS_MAP[alias] || alias;
|
|
3340
|
+
}
|
|
2565
3341
|
var PRIMITIVE_TYPE_SIZES = {
|
|
2566
3342
|
f32: 4,
|
|
2567
3343
|
f16: 2,
|
|
@@ -2880,7 +3656,9 @@ __publicField(QuerySet, "defaultProps", {
|
|
|
2880
3656
|
|
|
2881
3657
|
// dist/adapter/resources/fence.js
|
|
2882
3658
|
var _Fence = class extends Resource {
|
|
2883
|
-
[Symbol.toStringTag]
|
|
3659
|
+
get [Symbol.toStringTag]() {
|
|
3660
|
+
return "Fence";
|
|
3661
|
+
}
|
|
2884
3662
|
constructor(device, props = {}) {
|
|
2885
3663
|
super(device, props, _Fence.defaultProps);
|
|
2886
3664
|
}
|
|
@@ -3040,20 +3818,26 @@ function isNumberArray(value) {
|
|
|
3040
3818
|
}
|
|
3041
3819
|
|
|
3042
3820
|
// dist/utils/array-equal.js
|
|
3821
|
+
var MAX_ELEMENTWISE_ARRAY_COMPARE_LENGTH = 128;
|
|
3043
3822
|
function arrayEqual(a, b, limit = 16) {
|
|
3044
|
-
if (a
|
|
3045
|
-
return
|
|
3823
|
+
if (a === b) {
|
|
3824
|
+
return true;
|
|
3046
3825
|
}
|
|
3047
3826
|
const arrayA = a;
|
|
3048
3827
|
const arrayB = b;
|
|
3049
|
-
if (!isNumberArray(arrayA)) {
|
|
3828
|
+
if (!isNumberArray(arrayA) || !isNumberArray(arrayB)) {
|
|
3050
3829
|
return false;
|
|
3051
3830
|
}
|
|
3052
|
-
if (
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3831
|
+
if (arrayA.length !== arrayB.length) {
|
|
3832
|
+
return false;
|
|
3833
|
+
}
|
|
3834
|
+
const maxCompareLength = Math.min(limit, MAX_ELEMENTWISE_ARRAY_COMPARE_LENGTH);
|
|
3835
|
+
if (arrayA.length > maxCompareLength) {
|
|
3836
|
+
return false;
|
|
3837
|
+
}
|
|
3838
|
+
for (let i = 0; i < arrayA.length; ++i) {
|
|
3839
|
+
if (arrayB[i] !== arrayA[i]) {
|
|
3840
|
+
return false;
|
|
3057
3841
|
}
|
|
3058
3842
|
}
|
|
3059
3843
|
return true;
|
|
@@ -3273,7 +4057,7 @@ function readPixel(pixelData, x, y, bitsPerChannel) {
|
|
|
3273
4057
|
let bitOffsetWithinPixel = 0;
|
|
3274
4058
|
const channels = [];
|
|
3275
4059
|
for (let i = 0; i < 4; i++) {
|
|
3276
|
-
const bits = bitsPerChannel[i];
|
|
4060
|
+
const bits = bitsPerChannel[i] ?? 0;
|
|
3277
4061
|
if (bits <= 0) {
|
|
3278
4062
|
channels.push(0);
|
|
3279
4063
|
} else {
|
|
@@ -3282,14 +4066,14 @@ function readPixel(pixelData, x, y, bitsPerChannel) {
|
|
|
3282
4066
|
bitOffsetWithinPixel += bits;
|
|
3283
4067
|
}
|
|
3284
4068
|
}
|
|
3285
|
-
return [channels[0], channels[1], channels[2], channels[3]];
|
|
4069
|
+
return [channels[0] ?? 0, channels[1] ?? 0, channels[2] ?? 0, channels[3] ?? 0];
|
|
3286
4070
|
}
|
|
3287
4071
|
function writePixel(dataView, bitOffset, bitsPerChannel, pixel) {
|
|
3288
4072
|
let currentBitOffset = bitOffset;
|
|
3289
4073
|
for (let channel = 0; channel < 4; channel++) {
|
|
3290
|
-
const bits = bitsPerChannel[channel];
|
|
4074
|
+
const bits = bitsPerChannel[channel] ?? 0;
|
|
3291
4075
|
const maxValue = (1 << bits) - 1;
|
|
3292
|
-
const channelValue = pixel[channel] & maxValue;
|
|
4076
|
+
const channelValue = (pixel[channel] ?? 0) & maxValue;
|
|
3293
4077
|
writeBitsToDataView(dataView, currentBitOffset, bits, channelValue);
|
|
3294
4078
|
currentBitOffset += bits;
|
|
3295
4079
|
}
|