@solidtv/renderer 1.4.1 → 1.5.0-0
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/src/core/Stage.js +2 -1
- package/dist/src/core/Stage.js.map +1 -1
- package/dist/src/core/lib/WebGlContextWrapper.d.ts +53 -3
- package/dist/src/core/lib/WebGlContextWrapper.js +96 -2
- package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -1
- package/dist/src/core/renderers/CoreRenderer.d.ts +37 -0
- package/dist/src/core/renderers/CoreRenderer.js.map +1 -1
- package/dist/src/core/renderers/canvas/CanvasRenderer.d.ts +2 -1
- package/dist/src/core/renderers/canvas/CanvasRenderer.js +10 -1
- package/dist/src/core/renderers/canvas/CanvasRenderer.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlRenderer.d.ts +10 -1
- package/dist/src/core/renderers/webgl/WebGlRenderer.js +20 -2
- package/dist/src/core/renderers/webgl/WebGlRenderer.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlShaderProgram.d.ts +22 -0
- package/dist/src/core/renderers/webgl/WebGlShaderProgram.js +61 -0
- package/dist/src/core/renderers/webgl/WebGlShaderProgram.js.map +1 -1
- package/dist/src/core/renderers/webgl/internal/RendererUtils.d.ts +1 -1
- package/dist/src/core/renderers/webgl/internal/RendererUtils.js +1 -0
- package/dist/src/core/renderers/webgl/internal/RendererUtils.js.map +1 -1
- package/dist/src/main-api/Renderer.d.ts +26 -0
- package/dist/src/main-api/Renderer.js +19 -0
- package/dist/src/main-api/Renderer.js.map +1 -1
- package/dist/src/utils.d.ts +1 -1
- package/dist/src/utils.js +2 -2
- package/dist/src/utils.js.map +1 -1
- package/dist/tsconfig.dist.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/core/Stage.ts +2 -0
- package/src/core/lib/WebGlContextWrapper.ts +103 -3
- package/src/core/renderers/CoreRenderer.ts +38 -0
- package/src/core/renderers/canvas/CanvasRenderer.test.ts +14 -0
- package/src/core/renderers/canvas/CanvasRenderer.ts +15 -1
- package/src/core/renderers/webgl/WebGlRenderer.ts +27 -2
- package/src/core/renderers/webgl/WebGlShaderProgram.ts +70 -0
- package/src/core/renderers/webgl/internal/RendererUtils.ts +5 -1
- package/src/main-api/Renderer.ts +32 -0
- package/src/utils.ts +2 -1
|
@@ -30,6 +30,19 @@ export class WebGlShaderProgram implements CoreShaderProgram {
|
|
|
30
30
|
public isDestroyed = false;
|
|
31
31
|
supportsIndexedTextures = false;
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Cached Vertex Array Objects, keyed by the buffer collection they capture.
|
|
35
|
+
*
|
|
36
|
+
* @remarks
|
|
37
|
+
* A VAO records this program's attribute layout (enabled arrays, pointers and
|
|
38
|
+
* their source buffers) plus the shared element index buffer, so a draw only
|
|
39
|
+
* needs a single `bindVertexArray` instead of re-pointing every attribute. In
|
|
40
|
+
* practice a program only ever binds one collection, but keying by collection
|
|
41
|
+
* keeps it correct if that ever changes. Empty / unused when the context has
|
|
42
|
+
* no VAO support (see {@link WebGlContextWrapper.canUseVertexArrayObject}).
|
|
43
|
+
*/
|
|
44
|
+
protected vaos = new Map<BufferCollection, WebGLVertexArrayObject | null>();
|
|
45
|
+
|
|
33
46
|
constructor(
|
|
34
47
|
renderer: WebGlRenderer,
|
|
35
48
|
config: WebGlShaderType,
|
|
@@ -259,6 +272,30 @@ export class WebGlShaderProgram implements CoreShaderProgram {
|
|
|
259
272
|
|
|
260
273
|
bindBufferCollection(buffer: BufferCollection) {
|
|
261
274
|
const { glw } = this;
|
|
275
|
+
|
|
276
|
+
if (glw.canUseVertexArrayObject === true) {
|
|
277
|
+
let vao = this.vaos.get(buffer);
|
|
278
|
+
if (vao === undefined) {
|
|
279
|
+
// First draw with this collection: record the attribute layout into a
|
|
280
|
+
// VAO. createVao leaves the new VAO bound, so there's nothing more to do.
|
|
281
|
+
vao = this.createVao(buffer);
|
|
282
|
+
this.vaos.set(buffer, vao);
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
glw.bindVertexArray(vao);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// No VAO support: re-point every attribute on each draw.
|
|
290
|
+
this.bindAttributes(buffer);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Point this program's vertex attributes at the given buffer collection.
|
|
295
|
+
* When a VAO is bound this records into it; otherwise it mutates global state.
|
|
296
|
+
*/
|
|
297
|
+
private bindAttributes(buffer: BufferCollection) {
|
|
298
|
+
const { glw } = this;
|
|
262
299
|
const attribs = this.attributeLocations;
|
|
263
300
|
const attribLen = attribs.length;
|
|
264
301
|
|
|
@@ -282,6 +319,25 @@ export class WebGlShaderProgram implements CoreShaderProgram {
|
|
|
282
319
|
}
|
|
283
320
|
}
|
|
284
321
|
|
|
322
|
+
/**
|
|
323
|
+
* Create and populate a Vertex Array Object capturing this program's
|
|
324
|
+
* attribute layout for the given buffer collection. The new VAO is left bound.
|
|
325
|
+
*/
|
|
326
|
+
private createVao(buffer: BufferCollection): WebGLVertexArrayObject | null {
|
|
327
|
+
const { glw } = this;
|
|
328
|
+
const vao = glw.createVertexArray();
|
|
329
|
+
glw.bindVertexArray(vao);
|
|
330
|
+
|
|
331
|
+
this.bindAttributes(buffer);
|
|
332
|
+
|
|
333
|
+
// The element-array binding is part of VAO state and starts out null on a
|
|
334
|
+
// fresh VAO, so record the shared index buffer into it or indexed
|
|
335
|
+
// drawElements would read from no buffer.
|
|
336
|
+
glw.bindElementArrayBuffer(this.renderer.indexBuffer);
|
|
337
|
+
|
|
338
|
+
return vao;
|
|
339
|
+
}
|
|
340
|
+
|
|
285
341
|
bindTextures(textures: WebGlCtxTexture[]) {
|
|
286
342
|
const t = textures[0];
|
|
287
343
|
if (t === undefined) {
|
|
@@ -299,6 +355,13 @@ export class WebGlShaderProgram implements CoreShaderProgram {
|
|
|
299
355
|
}
|
|
300
356
|
|
|
301
357
|
detach(): void {
|
|
358
|
+
// With VAOs the enabled-attribute state lives in each per-collection VAO,
|
|
359
|
+
// not in global context state. Disabling here would mutate whichever VAO is
|
|
360
|
+
// currently bound and corrupt it for the next draw, so there's nothing to
|
|
361
|
+
// do on a program switch.
|
|
362
|
+
if (this.glw.canUseVertexArrayObject === true) {
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
302
365
|
this.disableAttributes();
|
|
303
366
|
}
|
|
304
367
|
|
|
@@ -310,6 +373,13 @@ export class WebGlShaderProgram implements CoreShaderProgram {
|
|
|
310
373
|
|
|
311
374
|
this.detach();
|
|
312
375
|
|
|
376
|
+
for (const vao of this.vaos.values()) {
|
|
377
|
+
if (vao !== null) {
|
|
378
|
+
glw.deleteVertexArray(vao);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
this.vaos.clear();
|
|
382
|
+
|
|
313
383
|
glw.deleteProgram(this.program!);
|
|
314
384
|
this.program = null;
|
|
315
385
|
this.uniformLocations = null;
|
|
@@ -7,7 +7,10 @@ import type { WebGlContextWrapper } from '../../../lib/WebGlContextWrapper.js';
|
|
|
7
7
|
* @param glw
|
|
8
8
|
* @param size
|
|
9
9
|
*/
|
|
10
|
-
export function createIndexBuffer(
|
|
10
|
+
export function createIndexBuffer(
|
|
11
|
+
glw: WebGlContextWrapper,
|
|
12
|
+
size: number,
|
|
13
|
+
): WebGLBuffer | null {
|
|
11
14
|
const maxQuads = ~~(size / 80);
|
|
12
15
|
const indices = new Uint16Array(maxQuads * 6);
|
|
13
16
|
|
|
@@ -22,6 +25,7 @@ export function createIndexBuffer(glw: WebGlContextWrapper, size: number) {
|
|
|
22
25
|
|
|
23
26
|
const buffer = glw.createBuffer();
|
|
24
27
|
glw.elementArrayBufferData(buffer, indices, glw.STATIC_DRAW);
|
|
28
|
+
return buffer;
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
/**
|
package/src/main-api/Renderer.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type { CanvasRenderer } from '../core/renderers/canvas/CanvasRenderer.js'
|
|
|
14
14
|
import type { WebGlRenderer } from '../core/renderers/webgl/WebGlRenderer.js';
|
|
15
15
|
import type { Inspector, InspectorOptions } from './Inspector.js';
|
|
16
16
|
import type { CoreShaderNode } from '../core/renderers/CoreShaderNode.js';
|
|
17
|
+
import type { RendererCapabilities } from '../core/renderers/CoreRenderer.js';
|
|
17
18
|
import type {
|
|
18
19
|
ExtractShaderProps,
|
|
19
20
|
OptionalShaderProps,
|
|
@@ -514,6 +515,17 @@ export type RendererMainSettings = RendererRuntimeSettings & {
|
|
|
514
515
|
*/
|
|
515
516
|
textBaselineMode: TextBaselineMode;
|
|
516
517
|
|
|
518
|
+
/**
|
|
519
|
+
* Force WebGL2
|
|
520
|
+
*
|
|
521
|
+
* @remarks
|
|
522
|
+
* Force the renderer to use WebGL2. This can be used to force the renderer to
|
|
523
|
+
* use WebGL2 even if the browser supports WebGL1.
|
|
524
|
+
*
|
|
525
|
+
* @defaultValue `false`
|
|
526
|
+
*/
|
|
527
|
+
forceWebGL2: boolean;
|
|
528
|
+
|
|
517
529
|
/**
|
|
518
530
|
* Canvas object to use for rendering
|
|
519
531
|
*
|
|
@@ -688,6 +700,7 @@ export class RendererMain extends EventEmitter {
|
|
|
688
700
|
numImageWorkers:
|
|
689
701
|
settings.numImageWorkers !== undefined ? settings.numImageWorkers : 2,
|
|
690
702
|
enableContextSpy: settings.enableContextSpy ?? false,
|
|
703
|
+
forceWebGL2: settings.forceWebGL2 ?? false,
|
|
691
704
|
inspector: settings.inspector ?? false,
|
|
692
705
|
inspectorOptions: settings.inspectorOptions ?? {},
|
|
693
706
|
renderEngine: settings.renderEngine,
|
|
@@ -749,6 +762,7 @@ export class RendererMain extends EventEmitter {
|
|
|
749
762
|
deviceLogicalPixelRatio,
|
|
750
763
|
devicePhysicalPixelRatio,
|
|
751
764
|
enableContextSpy: settings.enableContextSpy!,
|
|
765
|
+
forceWebGL2: settings.forceWebGL2!,
|
|
752
766
|
fpsUpdateInterval: settings.fpsUpdateInterval!,
|
|
753
767
|
enableClear: settings.enableClear!,
|
|
754
768
|
numImageWorkers: settings.numImageWorkers!,
|
|
@@ -1022,6 +1036,24 @@ export class RendererMain extends EventEmitter {
|
|
|
1022
1036
|
return this.stage.renderer.getBufferInfo();
|
|
1023
1037
|
}
|
|
1024
1038
|
|
|
1039
|
+
/**
|
|
1040
|
+
* Report the active rendering backend and device capabilities.
|
|
1041
|
+
*
|
|
1042
|
+
* @remarks
|
|
1043
|
+
* Useful for diagnostics and field logging — e.g. confirming which WebGL
|
|
1044
|
+
* version a device negotiated and whether Vertex Array Objects engaged.
|
|
1045
|
+
* Reads live GL parameters (CPU↔GPU round-trips), so call once at startup
|
|
1046
|
+
* rather than per frame.
|
|
1047
|
+
*
|
|
1048
|
+
* @example
|
|
1049
|
+
* ```ts
|
|
1050
|
+
* console.table(renderer.getCapabilities());
|
|
1051
|
+
* ```
|
|
1052
|
+
*/
|
|
1053
|
+
getCapabilities(): RendererCapabilities {
|
|
1054
|
+
return this.stage.renderer.getCapabilities();
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1025
1057
|
/**
|
|
1026
1058
|
* Re-render the current frame without advancing any running animations.
|
|
1027
1059
|
*
|
package/src/utils.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { ContextSpy } from './core/lib/ContextSpy.js';
|
|
|
2
2
|
|
|
3
3
|
export function createWebGLContext(
|
|
4
4
|
canvas: HTMLCanvasElement | OffscreenCanvas,
|
|
5
|
+
forceWebGL2 = false,
|
|
5
6
|
contextSpy: ContextSpy | null,
|
|
6
7
|
): WebGLRenderingContext {
|
|
7
8
|
const config: WebGLContextAttributes = {
|
|
@@ -19,7 +20,7 @@ export function createWebGLContext(
|
|
|
19
20
|
const gl =
|
|
20
21
|
// TODO: Remove this assertion once this issue is fixed in TypeScript
|
|
21
22
|
// https://github.com/microsoft/TypeScript/issues/53614
|
|
22
|
-
(canvas.getContext('webgl', config) ||
|
|
23
|
+
(canvas.getContext(forceWebGL2 ? 'webgl2' : 'webgl', config) ||
|
|
23
24
|
canvas.getContext(
|
|
24
25
|
'experimental-webgl' as 'webgl',
|
|
25
26
|
config,
|