@luma.gl/engine 9.1.0-alpha.9 → 9.1.0-beta.1

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.
Files changed (196) hide show
  1. package/dist/animation/key-frames.js +1 -0
  2. package/dist/animation/key-frames.js.map +1 -0
  3. package/dist/animation/timeline.js +1 -0
  4. package/dist/animation/timeline.js.map +1 -0
  5. package/dist/animation-loop/animation-loop-template.js +1 -0
  6. package/dist/animation-loop/animation-loop-template.js.map +1 -0
  7. package/dist/animation-loop/animation-loop.d.ts +2 -0
  8. package/dist/animation-loop/animation-loop.d.ts.map +1 -1
  9. package/dist/animation-loop/animation-loop.js +24 -6
  10. package/dist/animation-loop/animation-loop.js.map +1 -0
  11. package/dist/animation-loop/animation-props.js +1 -0
  12. package/dist/animation-loop/animation-props.js.map +1 -0
  13. package/dist/animation-loop/make-animation-loop.d.ts +5 -1
  14. package/dist/animation-loop/make-animation-loop.d.ts.map +1 -1
  15. package/dist/animation-loop/make-animation-loop.js +3 -1
  16. package/dist/animation-loop/make-animation-loop.js.map +1 -0
  17. package/dist/animation-loop/request-animation-frame.d.ts +4 -2
  18. package/dist/animation-loop/request-animation-frame.d.ts.map +1 -1
  19. package/dist/animation-loop/request-animation-frame.js +5 -3
  20. package/dist/animation-loop/request-animation-frame.js.map +1 -0
  21. package/dist/application-utils/load-file.d.ts +1 -1
  22. package/dist/application-utils/load-file.d.ts.map +1 -1
  23. package/dist/application-utils/load-file.js +2 -2
  24. package/dist/application-utils/load-file.js.map +1 -0
  25. package/dist/application-utils/random.js +1 -0
  26. package/dist/application-utils/random.js.map +1 -0
  27. package/dist/async-texture/async-texture.d.ts +14 -2
  28. package/dist/async-texture/async-texture.d.ts.map +1 -1
  29. package/dist/async-texture/async-texture.js +31 -0
  30. package/dist/async-texture/async-texture.js.map +1 -0
  31. package/dist/compute/buffer-transform.d.ts +41 -0
  32. package/dist/compute/buffer-transform.d.ts.map +1 -0
  33. package/dist/{transform → compute}/buffer-transform.js +19 -12
  34. package/dist/compute/buffer-transform.js.map +1 -0
  35. package/dist/{computation.d.ts → compute/computation.d.ts} +3 -3
  36. package/dist/compute/computation.d.ts.map +1 -0
  37. package/dist/{computation.js → compute/computation.js} +7 -8
  38. package/dist/compute/computation.js.map +1 -0
  39. package/dist/compute/swap.d.ts +48 -0
  40. package/dist/compute/swap.d.ts.map +1 -0
  41. package/dist/compute/swap.js +91 -0
  42. package/dist/compute/swap.js.map +1 -0
  43. package/dist/{transform → compute}/texture-transform.d.ts +0 -6
  44. package/dist/compute/texture-transform.d.ts.map +1 -0
  45. package/dist/{transform → compute}/texture-transform.js +10 -15
  46. package/dist/compute/texture-transform.js.map +1 -0
  47. package/dist/debug/copy-texture-to-image.js +1 -0
  48. package/dist/debug/copy-texture-to-image.js.map +1 -0
  49. package/dist/debug/debug-framebuffer.js +2 -1
  50. package/dist/debug/debug-framebuffer.js.map +1 -0
  51. package/dist/debug/debug-shader-layout.js +2 -1
  52. package/dist/debug/debug-shader-layout.js.map +1 -0
  53. package/dist/debug/pixel-data-utils.js +1 -0
  54. package/dist/debug/pixel-data-utils.js.map +1 -0
  55. package/dist/dist.dev.js +2697 -5857
  56. package/dist/dist.min.js +420 -103
  57. package/dist/{lib → factories}/pipeline-factory.d.ts +11 -1
  58. package/dist/factories/pipeline-factory.d.ts.map +1 -0
  59. package/dist/factories/pipeline-factory.js +181 -0
  60. package/dist/factories/pipeline-factory.js.map +1 -0
  61. package/dist/{lib → factories}/shader-factory.d.ts +5 -1
  62. package/dist/factories/shader-factory.d.ts.map +1 -0
  63. package/dist/{lib → factories}/shader-factory.js +39 -4
  64. package/dist/factories/shader-factory.js.map +1 -0
  65. package/dist/geometries/cone-geometry.js +1 -0
  66. package/dist/geometries/cone-geometry.js.map +1 -0
  67. package/dist/geometries/cube-geometry.js +1 -0
  68. package/dist/geometries/cube-geometry.js.map +1 -0
  69. package/dist/geometries/cylinder-geometry.js +1 -0
  70. package/dist/geometries/cylinder-geometry.js.map +1 -0
  71. package/dist/geometries/ico-sphere-geometry.js +1 -0
  72. package/dist/geometries/ico-sphere-geometry.js.map +1 -0
  73. package/dist/geometries/plane-geometry.js +1 -0
  74. package/dist/geometries/plane-geometry.js.map +1 -0
  75. package/dist/geometries/sphere-geometry.js +1 -0
  76. package/dist/geometries/sphere-geometry.js.map +1 -0
  77. package/dist/geometries/truncated-cone-geometry.js +1 -0
  78. package/dist/geometries/truncated-cone-geometry.js.map +1 -0
  79. package/dist/geometry/geometry-table.js +1 -0
  80. package/dist/geometry/geometry-table.js.map +1 -0
  81. package/dist/geometry/geometry-utils.js +1 -0
  82. package/dist/geometry/geometry-utils.js.map +1 -0
  83. package/dist/geometry/geometry.js +1 -0
  84. package/dist/geometry/geometry.js.map +1 -0
  85. package/dist/geometry/gpu-geometry.js +1 -0
  86. package/dist/geometry/gpu-geometry.js.map +1 -0
  87. package/dist/geometry/gpu-table.js +1 -0
  88. package/dist/geometry/gpu-table.js.map +1 -0
  89. package/dist/index.cjs +1416 -209
  90. package/dist/index.cjs.map +4 -4
  91. package/dist/index.d.ts +23 -12
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +19 -9
  94. package/dist/index.js.map +1 -0
  95. package/dist/model/model.d.ts +11 -10
  96. package/dist/model/model.d.ts.map +1 -1
  97. package/dist/model/model.js +93 -70
  98. package/dist/model/model.js.map +1 -0
  99. package/dist/model/split-uniforms-and-bindings.d.ts +1 -1
  100. package/dist/model/split-uniforms-and-bindings.d.ts.map +1 -1
  101. package/dist/model/split-uniforms-and-bindings.js +2 -1
  102. package/dist/model/split-uniforms-and-bindings.js.map +1 -0
  103. package/dist/models/billboard-texture-model.d.ts +23 -0
  104. package/dist/models/billboard-texture-model.d.ts.map +1 -0
  105. package/dist/models/billboard-texture-model.js +78 -0
  106. package/dist/models/billboard-texture-model.js.map +1 -0
  107. package/dist/models/billboard-texture-module.d.ts +10 -0
  108. package/dist/models/billboard-texture-module.d.ts.map +1 -0
  109. package/dist/models/billboard-texture-module.js +37 -0
  110. package/dist/models/billboard-texture-module.js.map +1 -0
  111. package/dist/{lib → models}/clip-space.d.ts +3 -1
  112. package/dist/models/clip-space.d.ts.map +1 -0
  113. package/dist/models/clip-space.js +77 -0
  114. package/dist/models/clip-space.js.map +1 -0
  115. package/dist/modules/picking/color-picking.d.ts +28 -0
  116. package/dist/modules/picking/color-picking.d.ts.map +1 -0
  117. package/dist/modules/picking/color-picking.js +177 -0
  118. package/dist/modules/picking/color-picking.js.map +1 -0
  119. package/dist/modules/picking/index-picking.d.ts +32 -0
  120. package/dist/modules/picking/index-picking.d.ts.map +1 -0
  121. package/dist/modules/picking/index-picking.js +148 -0
  122. package/dist/modules/picking/index-picking.js.map +1 -0
  123. package/dist/modules/picking/legacy-picking-manager.d.ts +27 -0
  124. package/dist/modules/picking/legacy-picking-manager.d.ts.map +1 -0
  125. package/dist/modules/picking/legacy-picking-manager.js +76 -0
  126. package/dist/modules/picking/legacy-picking-manager.js.map +1 -0
  127. package/dist/modules/picking/picking-manager.d.ts +45 -0
  128. package/dist/modules/picking/picking-manager.d.ts.map +1 -0
  129. package/dist/modules/picking/picking-manager.js +101 -0
  130. package/dist/modules/picking/picking-manager.js.map +1 -0
  131. package/dist/modules/picking/picking-uniforms.d.ts +79 -0
  132. package/dist/modules/picking/picking-uniforms.d.ts.map +1 -0
  133. package/dist/modules/picking/picking-uniforms.js +109 -0
  134. package/dist/modules/picking/picking-uniforms.js.map +1 -0
  135. package/dist/passes/get-fragment-shader.d.ts +12 -0
  136. package/dist/passes/get-fragment-shader.d.ts.map +1 -0
  137. package/dist/passes/get-fragment-shader.js +117 -0
  138. package/dist/passes/get-fragment-shader.js.map +1 -0
  139. package/dist/passes/shader-pass-renderer.d.ts +63 -0
  140. package/dist/passes/shader-pass-renderer.d.ts.map +1 -0
  141. package/dist/passes/shader-pass-renderer.js +197 -0
  142. package/dist/passes/shader-pass-renderer.js.map +1 -0
  143. package/dist/scenegraph/group-node.js +1 -0
  144. package/dist/scenegraph/group-node.js.map +1 -0
  145. package/dist/scenegraph/model-node.js +1 -0
  146. package/dist/scenegraph/model-node.js.map +1 -0
  147. package/dist/scenegraph/scenegraph-node.js +1 -0
  148. package/dist/scenegraph/scenegraph-node.js.map +1 -0
  149. package/dist/shader-inputs.d.ts +8 -21
  150. package/dist/shader-inputs.d.ts.map +1 -1
  151. package/dist/shader-inputs.js +15 -11
  152. package/dist/shader-inputs.js.map +1 -0
  153. package/dist/utils/deep-equal.js +1 -0
  154. package/dist/utils/deep-equal.js.map +1 -0
  155. package/dist/utils/uid.js +1 -0
  156. package/dist/utils/uid.js.map +1 -0
  157. package/package.json +6 -6
  158. package/src/animation-loop/animation-loop.ts +27 -6
  159. package/src/animation-loop/make-animation-loop.ts +8 -3
  160. package/src/animation-loop/request-animation-frame.ts +4 -3
  161. package/src/application-utils/load-file.ts +2 -4
  162. package/src/async-texture/async-texture.ts +39 -7
  163. package/src/{transform → compute}/buffer-transform.ts +30 -14
  164. package/src/{computation.ts → compute/computation.ts} +14 -8
  165. package/src/compute/swap.ts +116 -0
  166. package/src/{transform → compute}/texture-transform.ts +9 -18
  167. package/src/debug/debug-framebuffer.ts +1 -1
  168. package/src/debug/debug-shader-layout.ts +1 -1
  169. package/src/factories/pipeline-factory.ts +222 -0
  170. package/src/{lib → factories}/shader-factory.ts +41 -5
  171. package/src/index.ts +35 -16
  172. package/src/model/model.ts +133 -78
  173. package/src/model/split-uniforms-and-bindings.ts +4 -4
  174. package/src/models/billboard-texture-model.ts +98 -0
  175. package/src/models/billboard-texture-module.ts +49 -0
  176. package/src/models/clip-space.ts +88 -0
  177. package/src/modules/picking/README.md +88 -0
  178. package/src/modules/picking/color-picking.ts +190 -0
  179. package/src/modules/picking/index-picking.ts +156 -0
  180. package/src/modules/picking/legacy-picking-manager.ts +99 -0
  181. package/src/modules/picking/picking-manager.ts +137 -0
  182. package/src/modules/picking/picking-uniforms.ts +179 -0
  183. package/src/passes/get-fragment-shader.ts +129 -0
  184. package/src/passes/shader-pass-renderer.ts +252 -0
  185. package/src/shader-inputs.ts +27 -48
  186. package/dist/computation.d.ts.map +0 -1
  187. package/dist/lib/clip-space.d.ts.map +0 -1
  188. package/dist/lib/clip-space.js +0 -46
  189. package/dist/lib/pipeline-factory.d.ts.map +0 -1
  190. package/dist/lib/pipeline-factory.js +0 -98
  191. package/dist/lib/shader-factory.d.ts.map +0 -1
  192. package/dist/transform/buffer-transform.d.ts +0 -35
  193. package/dist/transform/buffer-transform.d.ts.map +0 -1
  194. package/dist/transform/texture-transform.d.ts.map +0 -1
  195. package/src/lib/clip-space.ts +0 -53
  196. package/src/lib/pipeline-factory.ts +0 -126
@@ -0,0 +1,222 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import type {RenderPipelineProps, ComputePipelineProps} from '@luma.gl/core';
6
+ import {Device, RenderPipeline, ComputePipeline, log} from '@luma.gl/core';
7
+ import {uid} from '../utils/uid';
8
+
9
+ export type PipelineFactoryProps = RenderPipelineProps;
10
+
11
+ type RenderPipelineCacheItem = {pipeline: RenderPipeline; useCount: number};
12
+ type ComputePipelineCacheItem = {pipeline: ComputePipeline; useCount: number};
13
+
14
+ /**
15
+ * Efficiently creates / caches pipelines
16
+ */
17
+ export class PipelineFactory {
18
+ static defaultProps: Required<PipelineFactoryProps> = {...RenderPipeline.defaultProps};
19
+
20
+ /** Get the singleton default pipeline factory for the specified device */
21
+ static getDefaultPipelineFactory(device: Device): PipelineFactory {
22
+ device._lumaData.defaultPipelineFactory =
23
+ device._lumaData.defaultPipelineFactory || new PipelineFactory(device);
24
+ return device._lumaData.defaultPipelineFactory as PipelineFactory;
25
+ }
26
+
27
+ readonly device: Device;
28
+ readonly cachingEnabled: boolean;
29
+ readonly destroyPolicy: 'unused' | 'never';
30
+ readonly debug: boolean;
31
+
32
+ private _hashCounter: number = 0;
33
+ private readonly _hashes: Record<string, number> = {};
34
+ private readonly _renderPipelineCache: Record<string, RenderPipelineCacheItem> = {};
35
+ private readonly _computePipelineCache: Record<string, ComputePipelineCacheItem> = {};
36
+
37
+ get [Symbol.toStringTag](): string {
38
+ return 'PipelineFactory';
39
+ }
40
+
41
+ toString(): string {
42
+ return `PipelineFactory(${this.device.id})`;
43
+ }
44
+
45
+ constructor(device: Device) {
46
+ this.device = device;
47
+ this.cachingEnabled = device.props._cachePipelines;
48
+ this.destroyPolicy = device.props._cacheDestroyPolicy;
49
+ this.debug = device.props.debugFactories;
50
+ }
51
+
52
+ /** Return a RenderPipeline matching supplied props. Reuses an equivalent pipeline if already created. */
53
+ createRenderPipeline(props: RenderPipelineProps): RenderPipeline {
54
+ if (!this.cachingEnabled) {
55
+ return this.device.createRenderPipeline(props);
56
+ }
57
+
58
+ const allProps: Required<RenderPipelineProps> = {...RenderPipeline.defaultProps, ...props};
59
+
60
+ const cache = this._renderPipelineCache;
61
+ const hash = this._hashRenderPipeline(allProps);
62
+
63
+ let pipeline: RenderPipeline = cache[hash]?.pipeline;
64
+ if (!pipeline) {
65
+ pipeline = this.device.createRenderPipeline({
66
+ ...allProps,
67
+ id: allProps.id ? `${allProps.id}-cached` : uid('unnamed-cached')
68
+ });
69
+ pipeline.hash = hash;
70
+ cache[hash] = {pipeline, useCount: 1};
71
+ if (this.debug) {
72
+ log.warn(`${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
73
+ }
74
+ } else {
75
+ cache[hash].useCount++;
76
+ if (this.debug) {
77
+ log.warn(
78
+ `${this}: ${cache[hash].pipeline} reused, count=${cache[hash].useCount}, (id=${props.id})`
79
+ )();
80
+ }
81
+ }
82
+
83
+ return pipeline;
84
+ }
85
+
86
+ /** Return a ComputePipeline matching supplied props. Reuses an equivalent pipeline if already created. */
87
+ createComputePipeline(props: ComputePipelineProps): ComputePipeline {
88
+ if (!this.cachingEnabled) {
89
+ return this.device.createComputePipeline(props);
90
+ }
91
+
92
+ const allProps: Required<ComputePipelineProps> = {...ComputePipeline.defaultProps, ...props};
93
+
94
+ const cache = this._computePipelineCache;
95
+ const hash = this._hashComputePipeline(allProps);
96
+
97
+ let pipeline: ComputePipeline = cache[hash]?.pipeline;
98
+ if (!pipeline) {
99
+ pipeline = this.device.createComputePipeline({
100
+ ...allProps,
101
+ id: allProps.id ? `${allProps.id}-cached` : undefined
102
+ });
103
+ pipeline.hash = hash;
104
+ cache[hash] = {pipeline, useCount: 1};
105
+ if (this.debug) {
106
+ log.warn(`${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
107
+ }
108
+ } else {
109
+ cache[hash].useCount++;
110
+ if (this.debug) {
111
+ log.warn(
112
+ `${this}: ${cache[hash].pipeline} reused, count=${cache[hash].useCount}, (id=${props.id})`
113
+ )();
114
+ }
115
+ }
116
+
117
+ return pipeline;
118
+ }
119
+
120
+ release(pipeline: RenderPipeline | ComputePipeline): void {
121
+ if (!this.cachingEnabled) {
122
+ pipeline.destroy();
123
+ return;
124
+ }
125
+
126
+ const cache = this._getCache(pipeline);
127
+ const hash = pipeline.hash;
128
+
129
+ cache[hash].useCount--;
130
+ if (cache[hash].useCount === 0) {
131
+ this._destroyPipeline(pipeline);
132
+ if (this.debug) {
133
+ log.warn(`${this}: ${pipeline} released and destroyed`)();
134
+ }
135
+ } else if (cache[hash].useCount < 0) {
136
+ log.error(`${this}: ${pipeline} released, useCount < 0, resetting`)();
137
+ cache[hash].useCount = 0;
138
+ } else if (this.debug) {
139
+ log.warn(`${this}: ${pipeline} released, count=${cache[hash].useCount}`)();
140
+ }
141
+ }
142
+
143
+ // PRIVATE
144
+
145
+ /** Destroy a cached pipeline, removing it from the cache (depending on destroy policy) */
146
+ private _destroyPipeline(pipeline: RenderPipeline | ComputePipeline): boolean {
147
+ const cache = this._getCache(pipeline);
148
+
149
+ switch (this.destroyPolicy) {
150
+ case 'never':
151
+ return false;
152
+ case 'unused':
153
+ delete cache[pipeline.hash];
154
+ pipeline.destroy();
155
+ return true;
156
+ }
157
+ }
158
+
159
+ /** Get the appropriate cache for the type of pipeline */
160
+ private _getCache(
161
+ pipeline: RenderPipeline | ComputePipeline
162
+ ): Record<string, RenderPipelineCacheItem> | Record<string, ComputePipelineCacheItem> {
163
+ let cache:
164
+ | Record<string, RenderPipelineCacheItem>
165
+ | Record<string, ComputePipelineCacheItem>
166
+ | undefined;
167
+ if (pipeline instanceof ComputePipeline) {
168
+ cache = this._computePipelineCache;
169
+ }
170
+ if (pipeline instanceof RenderPipeline) {
171
+ cache = this._renderPipelineCache;
172
+ }
173
+ if (!cache) {
174
+ throw new Error(`${this}`);
175
+ }
176
+ if (!cache[pipeline.hash]) {
177
+ throw new Error(`${this}: ${pipeline} matched incorrect entry`);
178
+ }
179
+ return cache;
180
+ }
181
+
182
+ /** Calculate a hash based on all the inputs for a compute pipeline */
183
+ private _hashComputePipeline(props: ComputePipelineProps): string {
184
+ const {type} = this.device;
185
+ const shaderHash = this._getHash(props.shader.source);
186
+ return `${type}/C/${shaderHash}`;
187
+ }
188
+
189
+ /** Calculate a hash based on all the inputs for a render pipeline */
190
+ private _hashRenderPipeline(props: RenderPipelineProps): string {
191
+ const vsHash = props.vs ? this._getHash(props.vs.source) : 0;
192
+ const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
193
+
194
+ // WebGL specific
195
+ // const {varyings = [], bufferMode = {}} = props;
196
+ // const varyingHashes = varyings.map((v) => this._getHash(v));
197
+ const varyingHash = '-'; // `${varyingHashes.join('/')}B${bufferMode}`
198
+ const bufferLayoutHash = this._getHash(JSON.stringify(props.bufferLayout));
199
+
200
+ const {type} = this.device;
201
+ switch (type) {
202
+ case 'webgl':
203
+ // WebGL is more dynamic
204
+ return `${type}/R/${vsHash}/${fsHash}V${varyingHash}BL${bufferLayoutHash}`;
205
+
206
+ case 'webgpu':
207
+ default:
208
+ // On WebGPU we need to rebuild the pipeline if topology, parameters or bufferLayout change
209
+ const parameterHash = this._getHash(JSON.stringify(props.parameters));
210
+ // TODO - Can json.stringify() generate different strings for equivalent objects if order of params is different?
211
+ // create a deepHash() to deduplicate?
212
+ return `${type}/R/${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${parameterHash}BL${bufferLayoutHash}`;
213
+ }
214
+ }
215
+
216
+ private _getHash(key: string): number {
217
+ if (this._hashes[key] === undefined) {
218
+ this._hashes[key] = this._hashCounter++;
219
+ }
220
+ return this._hashes[key];
221
+ }
222
+ }
@@ -2,7 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import {Device, Shader, ShaderProps} from '@luma.gl/core';
5
+ import {Device, Shader, ShaderProps, log} from '@luma.gl/core';
6
6
 
7
7
  /** Manages a cached pool of Shaders for reuse. */
8
8
  export class ShaderFactory {
@@ -15,17 +15,34 @@ export class ShaderFactory {
15
15
  }
16
16
 
17
17
  public readonly device: Device;
18
+ readonly cachingEnabled: boolean;
18
19
  readonly destroyPolicy: 'unused' | 'never';
20
+ readonly debug: boolean;
21
+
19
22
  private readonly _cache: Record<string, {shader: Shader; useCount: number}> = {};
20
23
 
24
+ get [Symbol.toStringTag](): string {
25
+ return 'ShaderFactory';
26
+ }
27
+
28
+ toString(): string {
29
+ return `${this[Symbol.toStringTag]}(${this.device.id})`;
30
+ }
31
+
21
32
  /** @internal */
22
33
  constructor(device: Device) {
23
34
  this.device = device;
24
- this.destroyPolicy = device.props._factoryDestroyPolicy;
35
+ this.cachingEnabled = device.props._cacheShaders;
36
+ this.destroyPolicy = device.props._cacheDestroyPolicy;
37
+ this.debug = true; // device.props.debugFactories;
25
38
  }
26
39
 
27
40
  /** Requests a {@link Shader} from the cache, creating a new Shader only if necessary. */
28
41
  createShader(props: ShaderProps): Shader {
42
+ if (!this.cachingEnabled) {
43
+ return this.device.createShader(props);
44
+ }
45
+
29
46
  const key = this._hashShader(props);
30
47
 
31
48
  let cacheEntry = this._cache[key];
@@ -34,15 +51,27 @@ export class ShaderFactory {
34
51
  ...props,
35
52
  id: props.id ? `${props.id}-cached` : undefined
36
53
  });
37
- this._cache[key] = cacheEntry = {shader, useCount: 0};
54
+ this._cache[key] = cacheEntry = {shader, useCount: 1};
55
+ if (this.debug) {
56
+ log.warn(`${this}: Created new shader ${shader.id}`)();
57
+ }
58
+ } else {
59
+ cacheEntry.useCount++;
60
+ if (this.debug) {
61
+ log.warn(`${this}: Reusing shader ${cacheEntry.shader.id} count=${cacheEntry.useCount}`)();
62
+ }
38
63
  }
39
64
 
40
- cacheEntry.useCount++;
41
65
  return cacheEntry.shader;
42
66
  }
43
67
 
44
68
  /** Releases a previously-requested {@link Shader}, destroying it if no users remain. */
45
69
  release(shader: Shader): void {
70
+ if (!this.cachingEnabled) {
71
+ shader.destroy();
72
+ return;
73
+ }
74
+
46
75
  const key = this._hashShader(shader);
47
76
  const cacheEntry = this._cache[key];
48
77
  if (cacheEntry) {
@@ -51,14 +80,21 @@ export class ShaderFactory {
51
80
  if (this.destroyPolicy === 'unused') {
52
81
  delete this._cache[key];
53
82
  cacheEntry.shader.destroy();
83
+ if (this.debug) {
84
+ log.warn(`${this}: Releasing shader ${shader.id}, destroyed`)();
85
+ }
54
86
  }
87
+ } else if (cacheEntry.useCount < 0) {
88
+ throw new Error(`ShaderFactory: Shader ${shader.id} released too many times`);
89
+ } else if (this.debug) {
90
+ log.warn(`${this}: Releasing shader ${shader.id} count=${cacheEntry.useCount}`)();
55
91
  }
56
92
  }
57
93
  }
58
94
 
59
95
  // PRIVATE
60
96
 
61
- private _hashShader(value: Shader | ShaderProps): string {
97
+ protected _hashShader(value: Shader | ShaderProps): string {
62
98
  return `${value.stage}:${value.source}`;
63
99
  }
64
100
  }
package/src/index.ts CHANGED
@@ -21,16 +21,19 @@ export type {ModelProps} from './model/model';
21
21
  export {Model} from './model/model';
22
22
 
23
23
  // Transforms
24
- export type {BufferTransformProps} from './transform/buffer-transform';
25
- export {BufferTransform} from './transform/buffer-transform';
26
- export type {TextureTransformProps} from './transform/texture-transform';
27
- export {TextureTransform} from './transform/texture-transform';
24
+ export type {BufferTransformProps} from './compute/buffer-transform';
25
+ export {BufferTransform} from './compute/buffer-transform';
26
+ export type {TextureTransformProps} from './compute/texture-transform';
27
+ export {TextureTransform} from './compute/texture-transform';
28
28
 
29
- export {PipelineFactory} from './lib/pipeline-factory';
30
- export {ShaderFactory} from './lib/shader-factory';
29
+ export {PipelineFactory} from './factories/pipeline-factory';
30
+ export {ShaderFactory} from './factories/shader-factory';
31
31
 
32
- // Utils
33
- export {ClipSpace} from './lib/clip-space';
32
+ // Models
33
+ export type {ClipSpaceProps} from './models/clip-space';
34
+ export {ClipSpace} from './models/clip-space';
35
+ export type {BackgroundTextureModelProps} from './models/billboard-texture-model';
36
+ export {BackgroundTextureModel} from './models/billboard-texture-model';
34
37
 
35
38
  // Scenegraph Core nodes
36
39
  export {ScenegraphNode} from './scenegraph/scenegraph-node';
@@ -60,19 +63,35 @@ export {SphereGeometry} from './geometries/sphere-geometry';
60
63
  export type {TruncatedConeGeometryProps} from './geometries/truncated-cone-geometry';
61
64
  export {TruncatedConeGeometry} from './geometries/truncated-cone-geometry';
62
65
 
66
+ export {ShaderInputs} from './shader-inputs';
67
+
63
68
  // Application Utilities
64
69
  export {makeRandomGenerator} from './application-utils/random';
65
70
  export {setPathPrefix, loadImage, loadImageBitmap} from './application-utils/load-file';
66
71
 
67
72
  // EXPERIMENTAL
68
- export type {ShaderModuleInputs} from './shader-inputs';
69
- export {ShaderInputs as _ShaderInputs} from './shader-inputs';
70
- export type {ComputationProps} from './computation';
71
- export {Computation} from './computation';
72
- export {
73
- requestAnimationFrame,
74
- cancelAnimationFrame
75
- } from './animation-loop/request-animation-frame';
73
+ export type {ShaderPassRendererProps} from './passes/shader-pass-renderer';
74
+ export {ShaderPassRenderer} from './passes/shader-pass-renderer';
75
+
76
+ export {Swap} from './compute/swap';
77
+ export {SwapBuffers} from './compute/swap';
78
+ export {SwapFramebuffers} from './compute/swap';
79
+
80
+ export type {ComputationProps} from './compute/computation';
81
+ export {Computation} from './compute/computation';
76
82
 
77
83
  export type {AsyncTextureProps} from './async-texture/async-texture';
78
84
  export {AsyncTexture} from './async-texture/async-texture';
85
+
86
+ export {PickingManager} from './modules/picking/picking-manager';
87
+ export {picking as indexPicking} from './modules/picking/index-picking';
88
+ export {picking as colorPicking} from './modules/picking/color-picking';
89
+
90
+ export {
91
+ requestAnimationFramePolyfill,
92
+ cancelAnimationFramePolyfill
93
+ } from './animation-loop/request-animation-frame';
94
+
95
+ // DEPRECATED
96
+
97
+ export {LegacyPickingManager} from './modules/picking/legacy-picking-manager';