@luma.gl/core
Advanced tools
Comparing version 9.0.0-alpha.47 to 9.0.0-alpha.48
@@ -33,4 +33,2 @@ import { StatsManager } from '../lib/utils/stats-manager'; | ||
}; | ||
export declare const DEFAULT_DEVICE_PROPS: Required<DeviceProps>; | ||
export type ShadingLanguage = 'glsl' | 'wgsl'; | ||
/** | ||
@@ -42,10 +40,19 @@ * Identifies the GPU vendor and driver. | ||
export type DeviceInfo = { | ||
/** Type of */ | ||
type: 'webgl' | 'webgl2' | 'webgpu'; | ||
vendor: string; | ||
renderer: string; | ||
/** version of driver */ | ||
version: string; | ||
/** type of GPU */ | ||
gpu: 'nvidia' | 'amd' | 'intel' | 'apple' | 'software' | 'unknown'; | ||
shadingLanguages: ShadingLanguage[]; | ||
shadingLanguageVersions: Record<string, string>; | ||
/** GPU driver backend. Can sometimes be sniffed */ | ||
gpuBackend?: 'angle' | 'metal' | 'unknown'; | ||
/** Shader language supported by device.createShader() */ | ||
shadingLanguage: 'glsl' | 'wgsl'; | ||
/** Highest supported shader language version (GLSL 3.00 = 300, GLSL 1.00 = 100) */ | ||
shadingLanguageVersion: number; | ||
/** The masked vendor string */ | ||
vendorMasked?: string; | ||
/** The masked renderer string */ | ||
rendererMasked?: string; | ||
@@ -91,2 +98,3 @@ }; | ||
export declare abstract class Device { | ||
static defaultProps: Required<DeviceProps>; | ||
get [Symbol.toStringTag](): string; | ||
@@ -93,0 +101,0 @@ static VERSION: string; |
@@ -7,16 +7,2 @@ let _Symbol$toStringTag; | ||
import { Buffer } from "./resources/buffer.js"; | ||
export const DEFAULT_DEVICE_PROPS = { | ||
id: null, | ||
type: 'best-available', | ||
canvas: null, | ||
container: null, | ||
webgl2: true, | ||
webgl1: true, | ||
manageState: true, | ||
width: 800, | ||
height: 600, | ||
debug: Boolean(log.get('debug')), | ||
break: [], | ||
gl: null | ||
}; | ||
_Symbol$toStringTag = Symbol.toStringTag; | ||
@@ -37,3 +23,3 @@ export class Device { | ||
this.props = { | ||
...DEFAULT_DEVICE_PROPS, | ||
...Device.defaultProps, | ||
...props | ||
@@ -85,3 +71,17 @@ }; | ||
} | ||
Device.defaultProps = { | ||
id: null, | ||
type: 'best-available', | ||
canvas: null, | ||
container: null, | ||
webgl2: true, | ||
webgl1: true, | ||
manageState: true, | ||
width: 800, | ||
height: 600, | ||
debug: Boolean(log.get('debug')), | ||
break: [], | ||
gl: null | ||
}; | ||
Device.VERSION = VERSION; | ||
//# sourceMappingURL=device.js.map |
@@ -7,4 +7,4 @@ import { TypedArray, TypedArrayConstructor } from '../..'; | ||
/** Get the vertex format for an attribute with TypedArray and size */ | ||
export declare function getVertexFormatFromAttribute(typedArray: TypedArray, size?: number): VertexFormat; | ||
export declare function getVertexFormatFromAttribute(typedArray: TypedArray, size: number, normalized?: boolean): VertexFormat; | ||
export {}; | ||
//# sourceMappingURL=vertex-format-from-attribute.d.ts.map |
@@ -43,3 +43,3 @@ export function getDataTypeFromTypedArray(arrayOrType) { | ||
} | ||
export function getVertexFormatFromAttribute(typedArray, size) { | ||
export function getVertexFormatFromAttribute(typedArray, size, normalized) { | ||
if (!size || size > 4) { | ||
@@ -49,3 +49,3 @@ throw new Error(`size ${size}`); | ||
const components = size; | ||
const dataType = getDataTypeFromTypedArray(typedArray); | ||
let dataType = getDataTypeFromTypedArray(typedArray); | ||
if (dataType === 'uint8' || dataType === 'sint8') { | ||
@@ -55,2 +55,5 @@ if (components === 1 || components === 3) { | ||
} | ||
if (normalized) { | ||
dataType = dataType.replace('int', 'norm'); | ||
} | ||
return `${dataType}x${components}`; | ||
@@ -62,2 +65,5 @@ } | ||
} | ||
if (normalized) { | ||
dataType = dataType.replace('int', 'norm'); | ||
} | ||
return `${dataType}x${components}`; | ||
@@ -64,0 +70,0 @@ } |
@@ -1,2 +0,3 @@ | ||
import type { Device, DeviceProps } from '../adapter/device'; | ||
import type { DeviceProps } from '../adapter/device'; | ||
import { Device } from '../adapter/device'; | ||
import { StatsManager } from './utils/stats-manager'; | ||
@@ -3,0 +4,0 @@ import type { Log } from '@probe.gl/log'; |
@@ -1,2 +0,2 @@ | ||
import { DEFAULT_DEVICE_PROPS } from "../adapter/device.js"; | ||
import { Device } from "../adapter/device.js"; | ||
import { lumaStats } from "./utils/stats-manager.js"; | ||
@@ -20,3 +20,3 @@ import { log } from "./utils/log.js"; | ||
static setDefaultDeviceProps(props) { | ||
Object.assign(DEFAULT_DEVICE_PROPS, props); | ||
Object.assign(Device.defaultProps, props); | ||
} | ||
@@ -26,3 +26,3 @@ static async createDevice() { | ||
props = { | ||
...DEFAULT_DEVICE_PROPS, | ||
...Device.defaultProps, | ||
...props | ||
@@ -33,8 +33,8 @@ }; | ||
} | ||
let Device; | ||
let DeviceClass; | ||
switch (props.type) { | ||
case 'webgpu': | ||
Device = deviceList.get('webgpu'); | ||
if (Device) { | ||
return await Device.create(props); | ||
DeviceClass = deviceList.get('webgpu'); | ||
if (DeviceClass) { | ||
return await DeviceClass.create(props); | ||
} | ||
@@ -45,11 +45,11 @@ break; | ||
case 'webgl2': | ||
Device = deviceList.get('webgl'); | ||
if (Device) { | ||
return await Device.create(props); | ||
DeviceClass = deviceList.get('webgl'); | ||
if (DeviceClass) { | ||
return await DeviceClass.create(props); | ||
} | ||
break; | ||
case 'best-available': | ||
Device = deviceList.get('webgl'); | ||
if (Device && Device.isSupported()) { | ||
return await Device.create(props); | ||
DeviceClass = deviceList.get('webgl'); | ||
if (DeviceClass && DeviceClass.isSupported()) { | ||
return await DeviceClass.create(props); | ||
} | ||
@@ -56,0 +56,0 @@ break; |
@@ -9,3 +9,3 @@ import type { ShaderUniformType } from '../../adapter/types/shader-types'; | ||
*/ | ||
export declare class UniformBlock<TUniforms extends Record<string, UniformValue>> { | ||
export declare class UniformBlock<TUniforms extends Record<string, UniformValue> = Record<string, UniformValue>> { | ||
name: string; | ||
@@ -12,0 +12,0 @@ uniforms: Record<keyof TUniforms, UniformValue>; |
@@ -7,2 +7,7 @@ import type { ShaderUniformType } from '../../adapter/types/shader-types'; | ||
import { UniformBufferLayout } from './uniform-buffer-layout'; | ||
export type ShaderModuleInputs = { | ||
uniformTypes?: Record<string, ShaderUniformType>; | ||
defaultProps?: Record<string, unknown>; | ||
defaultUniforms?: Record<string, UniformValue>; | ||
}; | ||
/** | ||
@@ -15,9 +20,9 @@ * A uniform store holds a uniform values for one or more uniform blocks, | ||
*/ | ||
export declare class UniformStore<TUniformGroups extends Record<string, Record<string, UniformValue>>> { | ||
export declare class UniformStore<TPropGroups extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>> { | ||
/** Stores the uniform values for each uniform block */ | ||
uniformBlocks: Record<keyof TUniformGroups, UniformBlock<Record<string, UniformValue>>>; | ||
uniformBlocks: Map<keyof TPropGroups, UniformBlock<Record<string, UniformValue>>>; | ||
/** Can generate data for a uniform buffer for each block from data */ | ||
uniformBufferLayouts: Record<keyof TUniformGroups, UniformBufferLayout>; | ||
uniformBufferLayouts: Map<keyof TPropGroups, UniformBufferLayout>; | ||
/** Actual buffer for the blocks */ | ||
uniformBuffers: Partial<Record<keyof TUniformGroups, Buffer>>; | ||
uniformBuffers: Map<keyof TPropGroups, Buffer>; | ||
/** | ||
@@ -27,4 +32,5 @@ * Create a new UniformStore instance | ||
*/ | ||
constructor(blocks: Record<keyof TUniformGroups, { | ||
constructor(blocks: Record<keyof TPropGroups, { | ||
uniformTypes?: Record<string, ShaderUniformType>; | ||
defaultProps?: Record<string, unknown>; | ||
defaultUniforms?: Record<string, UniformValue>; | ||
@@ -39,8 +45,8 @@ }>); | ||
setUniforms(uniforms: Partial<{ | ||
[group in keyof TUniformGroups]: Partial<TUniformGroups[group]>; | ||
[group in keyof TPropGroups]: Partial<TPropGroups[group]>; | ||
}>): void; | ||
/** Get the required minimum length of the uniform buffer */ | ||
getUniformBufferByteLength(uniformBufferName: keyof TUniformGroups): number; | ||
getUniformBufferByteLength(uniformBufferName: keyof TPropGroups): number; | ||
/** Get formatted binary memory that can be uploaded to a buffer */ | ||
getUniformBufferData(uniformBufferName: keyof TUniformGroups): Uint8Array; | ||
getUniformBufferData(uniformBufferName: keyof TPropGroups): Uint8Array; | ||
/** | ||
@@ -50,12 +56,12 @@ * Creates an unmanaged uniform buffer (umnanaged means that application is responsible for destroying it) | ||
*/ | ||
createUniformBuffer(device: Device, uniformBufferName: keyof TUniformGroups, uniforms?: Partial<{ | ||
[group in keyof TUniformGroups]: Partial<TUniformGroups[group]>; | ||
createUniformBuffer(device: Device, uniformBufferName: keyof TPropGroups, uniforms?: Partial<{ | ||
[group in keyof TPropGroups]: Partial<TPropGroups[group]>; | ||
}>): Buffer; | ||
/** Get the managed uniform buffer. "managed" resources are destroyed when the uniformStore is destroyed. */ | ||
getManagedUniformBuffer(device: Device, uniformBufferName: keyof TUniformGroups): Buffer; | ||
/** Update one uniform buffer. Only updates if values have changed */ | ||
updateUniformBuffer(uniformBufferName: keyof TUniformGroups): false | string; | ||
getManagedUniformBuffer(device: Device, uniformBufferName: keyof TPropGroups): Buffer; | ||
/** Updates all uniform buffers where values have changed */ | ||
updateUniformBuffers(): false | string; | ||
/** Update one uniform buffer. Only updates if values have changed */ | ||
updateUniformBuffer(uniformBufferName: keyof TPropGroups): false | string; | ||
} | ||
//# sourceMappingURL=uniform-store.d.ts.map |
@@ -7,12 +7,9 @@ import { Buffer } from "../../adapter/resources/buffer.js"; | ||
constructor(blocks) { | ||
this.uniformBlocks = void 0; | ||
this.uniformBufferLayouts = void 0; | ||
this.uniformBuffers = void 0; | ||
this.uniformBlocks = {}; | ||
this.uniformBufferLayouts = {}; | ||
this.uniformBuffers = {}; | ||
this.uniformBlocks = new Map(); | ||
this.uniformBufferLayouts = new Map(); | ||
this.uniformBuffers = new Map(); | ||
for (const [bufferName, block] of Object.entries(blocks)) { | ||
const uniformBufferName = bufferName; | ||
const uniformBufferLayout = new UniformBufferLayout(block.uniformTypes || {}); | ||
this.uniformBufferLayouts[uniformBufferName] = uniformBufferLayout; | ||
this.uniformBufferLayouts.set(uniformBufferName, uniformBufferLayout); | ||
const uniformBlock = new UniformBlock({ | ||
@@ -22,3 +19,3 @@ name: bufferName | ||
uniformBlock.setUniforms(block.defaultUniforms || {}); | ||
this.uniformBlocks[uniformBufferName] = uniformBlock; | ||
this.uniformBlocks.set(uniformBufferName, uniformBlock); | ||
} | ||
@@ -33,3 +30,3 @@ } | ||
for (const [blockName, uniformValues] of Object.entries(uniforms)) { | ||
this.uniformBlocks[blockName].setUniforms(uniformValues); | ||
this.uniformBlocks.get(blockName).setUniforms(uniformValues); | ||
} | ||
@@ -39,7 +36,7 @@ this.updateUniformBuffers(); | ||
getUniformBufferByteLength(uniformBufferName) { | ||
return this.uniformBufferLayouts[uniformBufferName].byteLength; | ||
return this.uniformBufferLayouts.get(uniformBufferName).byteLength; | ||
} | ||
getUniformBufferData(uniformBufferName) { | ||
const uniformValues = this.uniformBlocks[uniformBufferName].getAllUniforms(); | ||
return this.uniformBufferLayouts[uniformBufferName].getData(uniformValues); | ||
const uniformValues = this.uniformBlocks.get(uniformBufferName).getAllUniforms(); | ||
return this.uniformBufferLayouts.get(uniformBufferName).getData(uniformValues); | ||
} | ||
@@ -60,3 +57,3 @@ createUniformBuffer(device, uniformBufferName, uniforms) { | ||
getManagedUniformBuffer(device, uniformBufferName) { | ||
if (!this.uniformBuffers[uniformBufferName]) { | ||
if (!this.uniformBuffers.get(uniformBufferName)) { | ||
const byteLength = this.getUniformBufferByteLength(uniformBufferName); | ||
@@ -67,10 +64,20 @@ const uniformBuffer = device.createBuffer({ | ||
}); | ||
this.uniformBuffers[uniformBufferName] = uniformBuffer; | ||
this.uniformBuffers.set(uniformBufferName, uniformBuffer); | ||
} | ||
this.updateUniformBuffers(); | ||
return this.uniformBuffers[uniformBufferName]; | ||
return this.uniformBuffers.get(uniformBufferName); | ||
} | ||
updateUniformBuffers() { | ||
let reason = false; | ||
for (const uniformBufferName of this.uniformBlocks.keys()) { | ||
const bufferReason = this.updateUniformBuffer(uniformBufferName); | ||
reason || (reason = bufferReason); | ||
} | ||
if (reason) { | ||
log.log(3, `UniformStore.updateUniformBuffers(): ${reason}`)(); | ||
} | ||
return reason; | ||
} | ||
updateUniformBuffer(uniformBufferName) { | ||
const uniformBlock = this.uniformBlocks[uniformBufferName]; | ||
const uniformBuffer = this.uniformBuffers[uniformBufferName]; | ||
const uniformBlock = this.uniformBlocks.get(uniformBufferName); | ||
const uniformBuffer = this.uniformBuffers.get(uniformBufferName); | ||
let reason = false; | ||
@@ -80,5 +87,5 @@ if (uniformBuffer && uniformBlock.needsRedraw) { | ||
const uniformBufferData = this.getUniformBufferData(uniformBufferName); | ||
const uniformBuffer = this.uniformBuffers[uniformBufferName]; | ||
const uniformBuffer = this.uniformBuffers.get(uniformBufferName); | ||
uniformBuffer.write(uniformBufferData); | ||
const uniformValues = this.uniformBlocks[uniformBufferName].getAllUniforms(); | ||
const uniformValues = this.uniformBlocks.get(uniformBufferName).getAllUniforms(); | ||
log.log(4, `Writing to uniform buffer ${String(uniformBufferName)}`, uniformBufferData, uniformValues)(); | ||
@@ -88,13 +95,3 @@ } | ||
} | ||
updateUniformBuffers() { | ||
let reason = false; | ||
for (const uniformBufferName of Object.keys(this.uniformBlocks)) { | ||
reason || (reason = this.updateUniformBuffer(uniformBufferName)); | ||
} | ||
if (reason) { | ||
log.log(3, `UniformStore.updateUniformBuffers(): ${reason}`)(); | ||
} | ||
return reason; | ||
} | ||
} | ||
//# sourceMappingURL=uniform-store.js.map |
{ | ||
"name": "@luma.gl/core", | ||
"version": "9.0.0-alpha.47", | ||
"version": "9.0.0-alpha.48", | ||
"description": "luma.gl API", | ||
@@ -45,3 +45,3 @@ "license": "MIT", | ||
}, | ||
"gitHead": "7c6e28518021f98c7d0739f5cbdac386144206a1" | ||
"gitHead": "e57479712693a82ec918382020dd2593035e29b0" | ||
} |
@@ -57,28 +57,2 @@ // luma.gl, MIT license | ||
export const DEFAULT_DEVICE_PROPS: Required<DeviceProps> = { | ||
id: null!, | ||
type: 'best-available', | ||
canvas: null, | ||
container: null, | ||
webgl2: true, // Attempt to create a WebGL2 context | ||
webgl1: true, // Attempt to create a WebGL1 context (false to fail if webgl2 not available) | ||
manageState: true, | ||
width: 800, // width are height are only used by headless gl | ||
height: 600, | ||
debug: Boolean(log.get('debug')), // Instrument context (at the expense of performance) | ||
break: [], | ||
// alpha: undefined, | ||
// depth: undefined, | ||
// stencil: undefined, | ||
// antialias: undefined, | ||
// premultipliedAlpha: undefined, | ||
// preserveDrawingBuffer: undefined, | ||
// failIfMajorPerformanceCaveat: undefined | ||
gl: null | ||
}; | ||
export type ShadingLanguage = 'glsl' | 'wgsl'; | ||
/** | ||
@@ -90,10 +64,20 @@ * Identifies the GPU vendor and driver. | ||
export type DeviceInfo = { | ||
/** Type of */ | ||
type: 'webgl' | 'webgl2' | 'webgpu'; | ||
vendor: string; | ||
renderer: string; | ||
/** version of driver */ | ||
version: string; | ||
/** type of GPU */ | ||
gpu: 'nvidia' | 'amd' | 'intel' | 'apple' | 'software' | 'unknown'; | ||
shadingLanguages: ShadingLanguage[]; | ||
shadingLanguageVersions: Record<string, string>; | ||
/** GPU driver backend. Can sometimes be sniffed */ | ||
gpuBackend?: 'angle' | 'metal' | 'unknown'; | ||
/** Shader language supported by device.createShader() */ | ||
shadingLanguage: 'glsl' | 'wgsl'; | ||
/** Highest supported shader language version (GLSL 3.00 = 300, GLSL 1.00 = 100) */ | ||
shadingLanguageVersion: number; | ||
/** The masked vendor string */ | ||
vendorMasked?: string; | ||
/** The masked renderer string */ | ||
rendererMasked?: string; | ||
@@ -210,2 +194,28 @@ }; | ||
export abstract class Device { | ||
static defaultProps: Required<DeviceProps> = { | ||
id: null!, | ||
type: 'best-available', | ||
canvas: null, | ||
container: null, | ||
webgl2: true, // Attempt to create a WebGL2 context | ||
webgl1: true, // Attempt to create a WebGL1 context (false to fail if webgl2 not available) | ||
manageState: true, | ||
width: 800, // width are height are only used by headless gl | ||
height: 600, | ||
debug: Boolean(log.get('debug')), // Instrument context (at the expense of performance) | ||
break: [], | ||
// alpha: undefined, | ||
// depth: undefined, | ||
// stencil: undefined, | ||
// antialias: undefined, | ||
// premultipliedAlpha: undefined, | ||
// preserveDrawingBuffer: undefined, | ||
// failIfMajorPerformanceCaveat: undefined | ||
gl: null | ||
}; | ||
get [Symbol.toStringTag](): string { | ||
@@ -218,3 +228,3 @@ return 'Device'; | ||
constructor(props: DeviceProps) { | ||
this.props = {...DEFAULT_DEVICE_PROPS, ...props}; | ||
this.props = {...Device.defaultProps, ...props}; | ||
this.id = this.props.id || uid(this[Symbol.toStringTag].toLowerCase()); | ||
@@ -221,0 +231,0 @@ } |
@@ -9,2 +9,4 @@ // luma.gl, MIT licese | ||
type DataTypeNorm = 'unorm8' | 'snorm8'| 'unorm16' | 'snorm16'; | ||
export function getDataTypeFromTypedArray(arrayOrType: TypedArray | TypedArrayConstructor): DataType { | ||
@@ -57,3 +59,3 @@ const type = ArrayBuffer.isView(arrayOrType) ? arrayOrType.constructor : arrayOrType; | ||
/** Get the vertex format for an attribute with TypedArray and size */ | ||
export function getVertexFormatFromAttribute(typedArray: TypedArray, size?: number): VertexFormat { | ||
export function getVertexFormatFromAttribute(typedArray: TypedArray, size: number, normalized?: boolean): VertexFormat { | ||
if(!size || size > 4) { | ||
@@ -64,3 +66,3 @@ throw new Error(`size ${size}`); | ||
const components = size as 1 | 2 | 3 | 4; | ||
const dataType: DataType = getDataTypeFromTypedArray(typedArray); | ||
let dataType: DataType | DataTypeNorm = getDataTypeFromTypedArray(typedArray); | ||
@@ -72,2 +74,5 @@ if (dataType === 'uint8' || dataType === 'sint8') { | ||
} | ||
if (normalized) { | ||
dataType = dataType.replace('int', 'norm') as 'unorm8' | 'snorm8'; | ||
} | ||
return `${dataType}x${components}`; | ||
@@ -80,2 +85,5 @@ } | ||
} | ||
if (normalized) { | ||
dataType = dataType.replace('int', 'norm') as 'unorm16' | 'snorm16'; | ||
} | ||
return `${dataType}x${components}`; | ||
@@ -82,0 +90,0 @@ } |
// luma.gl, MIT license | ||
// Copyright (c) vis.gl contributors | ||
import type {Device, DeviceProps} from '../adapter/device'; | ||
import {DEFAULT_DEVICE_PROPS} from '../adapter/device'; | ||
import type {DeviceProps} from '../adapter/device'; | ||
import {Device} from '../adapter/device'; | ||
import {StatsManager} from './utils/stats-manager'; | ||
@@ -44,3 +44,3 @@ import {lumaStats} from './utils/stats-manager'; | ||
static setDefaultDeviceProps(props: DeviceProps): void { | ||
Object.assign(DEFAULT_DEVICE_PROPS, props); | ||
Object.assign(Device.defaultProps, props); | ||
} | ||
@@ -50,3 +50,3 @@ | ||
static async createDevice(props: DeviceProps = {}): Promise<Device> { | ||
props = {...DEFAULT_DEVICE_PROPS, ...props} | ||
props = {...Device.defaultProps, ...props} | ||
if (props.gl) { | ||
@@ -56,8 +56,8 @@ props.type = 'webgl'; | ||
let Device: any; | ||
let DeviceClass: any; | ||
switch (props.type) { | ||
case 'webgpu': | ||
Device = deviceList.get('webgpu'); | ||
if (Device) { | ||
return await Device.create(props); | ||
DeviceClass = deviceList.get('webgpu'); | ||
if (DeviceClass) { | ||
return await DeviceClass.create(props); | ||
} | ||
@@ -68,15 +68,15 @@ break; | ||
case 'webgl2': | ||
Device = deviceList.get('webgl'); | ||
if (Device) { | ||
return await Device.create(props); | ||
DeviceClass = deviceList.get('webgl'); | ||
if (DeviceClass) { | ||
return await DeviceClass.create(props); | ||
} | ||
break; | ||
case 'best-available': | ||
// Device = deviceList.get('webgpu'); | ||
// if (Device && Device.isSupported()) { | ||
// return await Device.create(props); | ||
// DeviceClass = deviceList.get('webgpu'); | ||
// if (DeviceClass && DeviceClass.isSupported()) { | ||
// return await DeviceClass.create(props); | ||
// } | ||
Device = deviceList.get('webgl'); | ||
if (Device && Device.isSupported()) { | ||
return await Device.create(props); | ||
DeviceClass = deviceList.get('webgl'); | ||
if (DeviceClass && DeviceClass.isSupported()) { | ||
return await DeviceClass.create(props); | ||
} | ||
@@ -83,0 +83,0 @@ break; |
@@ -16,3 +16,3 @@ // luma.gl, MIT license | ||
*/ | ||
export class UniformBlock<TUniforms extends Record<string, UniformValue>> { | ||
export class UniformBlock<TUniforms extends Record<string, UniformValue> = Record<string, UniformValue>> { | ||
name: string; | ||
@@ -19,0 +19,0 @@ |
@@ -10,2 +10,8 @@ // luma.gl, MIT license | ||
export type ShaderModuleInputs = { | ||
uniformTypes?: Record<string, ShaderUniformType>; | ||
defaultProps?: Record<string, unknown>; | ||
defaultUniforms?: Record<string, UniformValue>; | ||
}; | ||
/** | ||
@@ -18,9 +24,9 @@ * A uniform store holds a uniform values for one or more uniform blocks, | ||
*/ | ||
export class UniformStore<TUniformGroups extends Record<string, Record<string, UniformValue>>> { | ||
export class UniformStore<TPropGroups extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>> { | ||
/** Stores the uniform values for each uniform block */ | ||
uniformBlocks: Record<keyof TUniformGroups, UniformBlock<Record<string, UniformValue>>>; | ||
uniformBlocks = new Map<keyof TPropGroups, UniformBlock>; | ||
/** Can generate data for a uniform buffer for each block from data */ | ||
uniformBufferLayouts: Record<keyof TUniformGroups, UniformBufferLayout>; | ||
uniformBufferLayouts = new Map<keyof TPropGroups, UniformBufferLayout>; | ||
/** Actual buffer for the blocks */ | ||
uniformBuffers: Partial<Record<keyof TUniformGroups, Buffer>>; | ||
uniformBuffers = new Map<keyof TPropGroups, Buffer>; | ||
@@ -33,5 +39,6 @@ /** | ||
blocks: Record< | ||
keyof TUniformGroups, | ||
keyof TPropGroups, | ||
{ | ||
uniformTypes?: Record<string, ShaderUniformType>; | ||
defaultProps?: Record<string, unknown>; | ||
defaultUniforms?: Record<string, UniformValue>; | ||
@@ -41,15 +48,8 @@ } | ||
) { | ||
this.uniformBlocks = {} as Record< | ||
keyof TUniformGroups, | ||
UniformBlock<Record<string, UniformValue>> | ||
>; | ||
this.uniformBufferLayouts = {} as Record<keyof TUniformGroups, UniformBufferLayout>; | ||
this.uniformBuffers = {} as Record<keyof TUniformGroups, Buffer>; | ||
for (const [bufferName, block] of Object.entries(blocks)) { | ||
const uniformBufferName = bufferName as keyof TUniformGroups; | ||
const uniformBufferName = bufferName as keyof TPropGroups; | ||
// Create a layout object to help us generate correctly formatted binary uniform buffers | ||
const uniformBufferLayout = new UniformBufferLayout(block.uniformTypes || {}); | ||
this.uniformBufferLayouts[uniformBufferName] = uniformBufferLayout; | ||
this.uniformBufferLayouts.set(uniformBufferName, uniformBufferLayout); | ||
@@ -59,3 +59,3 @@ // Create a Uniform block to store the uniforms for each buffer. | ||
uniformBlock.setUniforms(block.defaultUniforms || {}); | ||
this.uniformBlocks[uniformBufferName] = uniformBlock; | ||
this.uniformBlocks.set(uniformBufferName, uniformBlock); | ||
} | ||
@@ -76,6 +76,6 @@ } | ||
setUniforms( | ||
uniforms: Partial<{[group in keyof TUniformGroups]: Partial<TUniformGroups[group]>}> | ||
uniforms: Partial<{[group in keyof TPropGroups]: Partial<TPropGroups[group]>}> | ||
): void { | ||
for (const [blockName, uniformValues] of Object.entries(uniforms)) { | ||
this.uniformBlocks[blockName].setUniforms(uniformValues); | ||
this.uniformBlocks.get(blockName).setUniforms(uniformValues); | ||
// We leverage logging in updateUniformBuffers(), even though slightly less efficient | ||
@@ -89,10 +89,10 @@ // this.updateUniformBuffer(blockName); | ||
/** Get the required minimum length of the uniform buffer */ | ||
getUniformBufferByteLength(uniformBufferName: keyof TUniformGroups): number { | ||
return this.uniformBufferLayouts[uniformBufferName].byteLength; | ||
getUniformBufferByteLength(uniformBufferName: keyof TPropGroups): number { | ||
return this.uniformBufferLayouts.get(uniformBufferName).byteLength; | ||
} | ||
/** Get formatted binary memory that can be uploaded to a buffer */ | ||
getUniformBufferData(uniformBufferName: keyof TUniformGroups): Uint8Array { | ||
const uniformValues = this.uniformBlocks[uniformBufferName].getAllUniforms(); | ||
return this.uniformBufferLayouts[uniformBufferName].getData(uniformValues); | ||
getUniformBufferData(uniformBufferName: keyof TPropGroups): Uint8Array { | ||
const uniformValues = this.uniformBlocks.get(uniformBufferName).getAllUniforms(); | ||
return this.uniformBufferLayouts.get(uniformBufferName).getData(uniformValues); | ||
} | ||
@@ -106,4 +106,4 @@ | ||
device: Device, | ||
uniformBufferName: keyof TUniformGroups, | ||
uniforms?: Partial<{[group in keyof TUniformGroups]: Partial<TUniformGroups[group]>}> | ||
uniformBufferName: keyof TPropGroups, | ||
uniforms?: Partial<{[group in keyof TPropGroups]: Partial<TPropGroups[group]>}> | ||
): Buffer { | ||
@@ -122,16 +122,29 @@ if (uniforms) { | ||
/** Get the managed uniform buffer. "managed" resources are destroyed when the uniformStore is destroyed. */ | ||
getManagedUniformBuffer(device: Device, uniformBufferName: keyof TUniformGroups): Buffer { | ||
if (!this.uniformBuffers[uniformBufferName]) { | ||
getManagedUniformBuffer(device: Device, uniformBufferName: keyof TPropGroups): Buffer { | ||
if (!this.uniformBuffers.get(uniformBufferName)) { | ||
const byteLength = this.getUniformBufferByteLength(uniformBufferName); | ||
const uniformBuffer = device.createBuffer({usage: Buffer.UNIFORM, byteLength}); | ||
this.uniformBuffers[uniformBufferName] = uniformBuffer; | ||
this.uniformBuffers.set(uniformBufferName, uniformBuffer); | ||
} | ||
this.updateUniformBuffers(); | ||
return this.uniformBuffers[uniformBufferName]; | ||
// this.updateUniformBuffers(); | ||
return this.uniformBuffers.get(uniformBufferName); | ||
} | ||
/** Updates all uniform buffers where values have changed */ | ||
updateUniformBuffers(): false | string { | ||
let reason: false | string = false; | ||
for (const uniformBufferName of this.uniformBlocks.keys()) { | ||
const bufferReason = this.updateUniformBuffer(uniformBufferName); | ||
reason ||= bufferReason; | ||
} | ||
if (reason) { | ||
log.log(3, `UniformStore.updateUniformBuffers(): ${reason}`)(); | ||
} | ||
return reason; | ||
} | ||
/** Update one uniform buffer. Only updates if values have changed */ | ||
updateUniformBuffer(uniformBufferName: keyof TUniformGroups): false | string { | ||
const uniformBlock = this.uniformBlocks[uniformBufferName]; | ||
const uniformBuffer = this.uniformBuffers[uniformBufferName]; | ||
updateUniformBuffer(uniformBufferName: keyof TPropGroups): false | string { | ||
const uniformBlock = this.uniformBlocks.get(uniformBufferName); | ||
const uniformBuffer = this.uniformBuffers.get(uniformBufferName); | ||
@@ -144,7 +157,7 @@ let reason: false | string = false; | ||
const uniformBuffer = this.uniformBuffers[uniformBufferName]; | ||
const uniformBuffer = this.uniformBuffers.get(uniformBufferName); | ||
uniformBuffer.write(uniformBufferData); | ||
// logging - TODO - don't query the values unnecessarily | ||
const uniformValues = this.uniformBlocks[uniformBufferName].getAllUniforms(); | ||
const uniformValues = this.uniformBlocks.get(uniformBufferName).getAllUniforms(); | ||
log.log( | ||
@@ -159,14 +172,2 @@ 4, | ||
} | ||
/** Updates all uniform buffers where values have changed */ | ||
updateUniformBuffers(): false | string { | ||
let reason: false | string = false; | ||
for (const uniformBufferName of Object.keys(this.uniformBlocks)) { | ||
reason ||= this.updateUniformBuffer(uniformBufferName); | ||
} | ||
if (reason) { | ||
log.log(3, `UniformStore.updateUniformBuffers(): ${reason}`)(); | ||
} | ||
return reason; | ||
} | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
967338
14359