@solidtv/renderer 1.4.2 → 1.5.0-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.
- package/dist/src/common/CommonTypes.d.ts +20 -0
- package/dist/src/core/Stage.d.ts +1 -0
- package/dist/src/core/Stage.js +11 -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 +36 -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 +19 -1
- package/dist/src/core/renderers/webgl/WebGlRenderer.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlShaderProgram.d.ts +24 -0
- package/dist/src/core/renderers/webgl/WebGlShaderProgram.js +74 -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 +33 -1
- package/dist/src/main-api/Renderer.js +17 -0
- package/dist/src/main-api/Renderer.js.map +1 -1
- package/dist/tsconfig.dist.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/common/CommonTypes.ts +20 -0
- package/src/core/Stage.ts +14 -1
- package/src/core/lib/WebGlContextWrapper.ts +103 -3
- package/src/core/renderers/CoreRenderer.ts +37 -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 +22 -1
- package/src/core/renderers/webgl/WebGlShaderProgram.ts +83 -0
- package/src/core/renderers/webgl/internal/RendererUtils.ts +5 -1
- package/src/main-api/Renderer.ts +36 -1
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
CoreRenderer,
|
|
10
10
|
type BufferInfo,
|
|
11
11
|
type CoreRendererOptions,
|
|
12
|
+
type RendererCapabilities,
|
|
12
13
|
} from '../CoreRenderer.js';
|
|
13
14
|
import { SdfRenderOp } from './SdfRenderOp.js';
|
|
14
15
|
import type { CoreContextTexture } from '../CoreContextTexture.js';
|
|
@@ -133,6 +134,15 @@ export class WebGlRenderer extends CoreRenderer {
|
|
|
133
134
|
defaultShaderNode: WebGlShaderNode | null = null;
|
|
134
135
|
quadBufferCollection: BufferCollection;
|
|
135
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Shared static element (index) buffer for quad rendering.
|
|
139
|
+
*
|
|
140
|
+
* @remarks
|
|
141
|
+
* Bound once globally, but also recorded into each shader program's Vertex
|
|
142
|
+
* Array Object since the element-array binding is part of VAO state.
|
|
143
|
+
*/
|
|
144
|
+
indexBuffer: WebGLBuffer | null = null;
|
|
145
|
+
|
|
136
146
|
clearColor: WebGlColor = {
|
|
137
147
|
raw: 0x00000000,
|
|
138
148
|
normalized: [0, 0, 0, 0],
|
|
@@ -187,7 +197,7 @@ export class WebGlRenderer extends CoreRenderer {
|
|
|
187
197
|
glw.setBlend(true);
|
|
188
198
|
glw.blendFunc(glw.ONE, glw.ONE_MINUS_SRC_ALPHA);
|
|
189
199
|
|
|
190
|
-
createIndexBuffer(glw, this.stage.bufferMemory);
|
|
200
|
+
this.indexBuffer = createIndexBuffer(glw, this.stage.bufferMemory);
|
|
191
201
|
|
|
192
202
|
// Create the static node coords buffer
|
|
193
203
|
// 80 is the magic number used in createIndexBuffer
|
|
@@ -1280,6 +1290,17 @@ export class WebGlRenderer extends CoreRenderer {
|
|
|
1280
1290
|
return bufferInfo;
|
|
1281
1291
|
}
|
|
1282
1292
|
|
|
1293
|
+
getCapabilities(): RendererCapabilities {
|
|
1294
|
+
const glw = this.glw;
|
|
1295
|
+
return {
|
|
1296
|
+
renderMode: 'webgl',
|
|
1297
|
+
webGlVersion: glw.isWebGl2 ? 2 : 1,
|
|
1298
|
+
vertexArrayObject: glw.canUseVertexArrayObject,
|
|
1299
|
+
maxTextureSize: glw.getParameter(glw.MAX_TEXTURE_SIZE) as number,
|
|
1300
|
+
maxTextureUnits: glw.getParameter(glw.MAX_TEXTURE_IMAGE_UNITS) as number,
|
|
1301
|
+
};
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1283
1304
|
/**
|
|
1284
1305
|
* Drain the GL error queue once and report whether a GL_OUT_OF_MEMORY was
|
|
1285
1306
|
* seen since the last call.
|
|
@@ -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,38 @@ 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: try to capture the attribute layout
|
|
280
|
+
// in a VAO. Cache the result — including a null on allocation failure,
|
|
281
|
+
// so we don't retry createVertexArray every frame.
|
|
282
|
+
vao = this.createVao(buffer);
|
|
283
|
+
this.vaos.set(buffer, vao);
|
|
284
|
+
}
|
|
285
|
+
if (vao !== null) {
|
|
286
|
+
// createVao leaves a freshly built VAO bound; re-binding is cheap and
|
|
287
|
+
// keeps the build and reuse paths identical.
|
|
288
|
+
glw.bindVertexArray(vao);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
// VAO allocation failed (e.g. under GL OOM). Bind the default VAO so the
|
|
292
|
+
// per-draw attribute setup below records into it rather than corrupting
|
|
293
|
+
// another program's cached VAO, then fall through.
|
|
294
|
+
glw.bindVertexArray(null);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// No (usable) VAO: re-point every attribute on each draw.
|
|
298
|
+
this.bindAttributes(buffer);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Point this program's vertex attributes at the given buffer collection.
|
|
303
|
+
* When a VAO is bound this records into it; otherwise it mutates global state.
|
|
304
|
+
*/
|
|
305
|
+
private bindAttributes(buffer: BufferCollection) {
|
|
306
|
+
const { glw } = this;
|
|
262
307
|
const attribs = this.attributeLocations;
|
|
263
308
|
const attribLen = attribs.length;
|
|
264
309
|
|
|
@@ -282,6 +327,30 @@ export class WebGlShaderProgram implements CoreShaderProgram {
|
|
|
282
327
|
}
|
|
283
328
|
}
|
|
284
329
|
|
|
330
|
+
/**
|
|
331
|
+
* Create and populate a Vertex Array Object capturing this program's
|
|
332
|
+
* attribute layout for the given buffer collection. The new VAO is left bound.
|
|
333
|
+
* Returns null if the context reports VAO support but allocation fails (e.g.
|
|
334
|
+
* under GL OOM), in which case the caller falls back to per-draw binding.
|
|
335
|
+
*/
|
|
336
|
+
private createVao(buffer: BufferCollection): WebGLVertexArrayObject | null {
|
|
337
|
+
const { glw } = this;
|
|
338
|
+
const vao = glw.createVertexArray();
|
|
339
|
+
if (vao === null) {
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
glw.bindVertexArray(vao);
|
|
343
|
+
|
|
344
|
+
this.bindAttributes(buffer);
|
|
345
|
+
|
|
346
|
+
// The element-array binding is part of VAO state and starts out null on a
|
|
347
|
+
// fresh VAO, so record the shared index buffer into it or indexed
|
|
348
|
+
// drawElements would read from no buffer.
|
|
349
|
+
glw.bindElementArrayBuffer(this.renderer.indexBuffer);
|
|
350
|
+
|
|
351
|
+
return vao;
|
|
352
|
+
}
|
|
353
|
+
|
|
285
354
|
bindTextures(textures: WebGlCtxTexture[]) {
|
|
286
355
|
const t = textures[0];
|
|
287
356
|
if (t === undefined) {
|
|
@@ -299,6 +368,13 @@ export class WebGlShaderProgram implements CoreShaderProgram {
|
|
|
299
368
|
}
|
|
300
369
|
|
|
301
370
|
detach(): void {
|
|
371
|
+
// With VAOs the enabled-attribute state lives in each per-collection VAO,
|
|
372
|
+
// not in global context state. Disabling here would mutate whichever VAO is
|
|
373
|
+
// currently bound and corrupt it for the next draw, so there's nothing to
|
|
374
|
+
// do on a program switch.
|
|
375
|
+
if (this.glw.canUseVertexArrayObject === true) {
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
302
378
|
this.disableAttributes();
|
|
303
379
|
}
|
|
304
380
|
|
|
@@ -310,6 +386,13 @@ export class WebGlShaderProgram implements CoreShaderProgram {
|
|
|
310
386
|
|
|
311
387
|
this.detach();
|
|
312
388
|
|
|
389
|
+
for (const vao of this.vaos.values()) {
|
|
390
|
+
if (vao !== null) {
|
|
391
|
+
glw.deleteVertexArray(vao);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
this.vaos.clear();
|
|
395
|
+
|
|
313
396
|
glw.deleteProgram(this.program!);
|
|
314
397
|
this.program = null;
|
|
315
398
|
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,
|
|
@@ -29,7 +30,8 @@ import { Platform } from '../core/platforms/Platform.js';
|
|
|
29
30
|
* @example
|
|
30
31
|
* ```typescript
|
|
31
32
|
* renderer.on('fpsUpdate', (_target, data) => {
|
|
32
|
-
* console.log(
|
|
33
|
+
* console.log(`${data.fps} fps, ${data.renderOps} draw calls`);
|
|
34
|
+
* console.log('backend:', data.capabilities.renderMode, data.capabilities.webGlVersion);
|
|
33
35
|
* if (data.contextSpyData) {
|
|
34
36
|
* console.log('WebGL calls:', data.contextSpyData);
|
|
35
37
|
* }
|
|
@@ -41,6 +43,21 @@ export interface RendererMainFpsUpdateEvent {
|
|
|
41
43
|
fps: number;
|
|
42
44
|
/** Context spy data (if enabled) - contains WebGL call statistics */
|
|
43
45
|
contextSpyData?: unknown;
|
|
46
|
+
/**
|
|
47
|
+
* Draw calls (render operations) submitted for the most recent frame.
|
|
48
|
+
* `0` on the Canvas backend.
|
|
49
|
+
*/
|
|
50
|
+
renderOps: number;
|
|
51
|
+
/** Quads rendered in the most recent frame. `0` on the Canvas backend. */
|
|
52
|
+
quads: number;
|
|
53
|
+
/**
|
|
54
|
+
* Active backend + device capabilities (constant for the renderer's
|
|
55
|
+
* lifetime). Included so each periodic sample is self-describing for
|
|
56
|
+
* telemetry — e.g. slice fps by `webGlVersion` or `vertexArrayObject`.
|
|
57
|
+
*
|
|
58
|
+
* @see {@link RendererCapabilities}
|
|
59
|
+
*/
|
|
60
|
+
capabilities: RendererCapabilities;
|
|
44
61
|
}
|
|
45
62
|
|
|
46
63
|
/**
|
|
@@ -1035,6 +1052,24 @@ export class RendererMain extends EventEmitter {
|
|
|
1035
1052
|
return this.stage.renderer.getBufferInfo();
|
|
1036
1053
|
}
|
|
1037
1054
|
|
|
1055
|
+
/**
|
|
1056
|
+
* Report the active rendering backend and device capabilities.
|
|
1057
|
+
*
|
|
1058
|
+
* @remarks
|
|
1059
|
+
* Useful for diagnostics and field logging — e.g. confirming which WebGL
|
|
1060
|
+
* version a device negotiated and whether Vertex Array Objects engaged.
|
|
1061
|
+
* Reads live GL parameters (CPU↔GPU round-trips), so call once at startup
|
|
1062
|
+
* rather than per frame.
|
|
1063
|
+
*
|
|
1064
|
+
* @example
|
|
1065
|
+
* ```ts
|
|
1066
|
+
* console.table(renderer.getCapabilities());
|
|
1067
|
+
* ```
|
|
1068
|
+
*/
|
|
1069
|
+
getCapabilities(): RendererCapabilities {
|
|
1070
|
+
return this.stage.renderer.getCapabilities();
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1038
1073
|
/**
|
|
1039
1074
|
* Re-render the current frame without advancing any running animations.
|
|
1040
1075
|
*
|