@lightningjs/renderer 3.0.2 → 3.0.4
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/README.md +56 -196
- package/dist/src/core/CoreNode.d.ts +2 -1
- package/dist/src/core/CoreNode.js +31 -7
- package/dist/src/core/CoreNode.js.map +1 -1
- package/dist/src/core/CoreTextNode.d.ts +26 -6
- package/dist/src/core/CoreTextNode.js +163 -60
- package/dist/src/core/CoreTextNode.js.map +1 -1
- package/dist/src/core/CoreTextureManager.d.ts +8 -0
- package/dist/src/core/CoreTextureManager.js +13 -1
- package/dist/src/core/CoreTextureManager.js.map +1 -1
- package/dist/src/core/Stage.d.ts +8 -0
- package/dist/src/core/Stage.js +23 -0
- package/dist/src/core/Stage.js.map +1 -1
- package/dist/src/core/TextureMemoryManager.d.ts +8 -13
- package/dist/src/core/TextureMemoryManager.js +22 -27
- package/dist/src/core/TextureMemoryManager.js.map +1 -1
- package/dist/src/core/lib/ImageWorker.d.ts +2 -2
- package/dist/src/core/lib/ImageWorker.js +31 -12
- package/dist/src/core/lib/ImageWorker.js.map +1 -1
- package/dist/src/core/lib/WebGlContextWrapper.d.ts +105 -56
- package/dist/src/core/lib/WebGlContextWrapper.js +164 -158
- package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -1
- package/dist/src/core/lib/fps.d.ts +15 -0
- package/dist/src/core/lib/fps.js +62 -0
- package/dist/src/core/lib/fps.js.map +1 -0
- package/dist/src/core/lib/textureCompression.js +19 -10
- package/dist/src/core/lib/textureCompression.js.map +1 -1
- package/dist/src/core/lib/validateImageBitmap.d.ts +2 -1
- package/dist/src/core/lib/validateImageBitmap.js +4 -4
- package/dist/src/core/lib/validateImageBitmap.js.map +1 -1
- package/dist/src/core/platform.js +2 -2
- package/dist/src/core/platform.js.map +1 -1
- package/dist/src/core/platforms/Platform.d.ts +4 -0
- package/dist/src/core/platforms/Platform.js.map +1 -1
- package/dist/src/core/platforms/web/WebPlatform.d.ts +2 -0
- package/dist/src/core/platforms/web/WebPlatform.js +13 -0
- package/dist/src/core/platforms/web/WebPlatform.js.map +1 -1
- package/dist/src/core/renderers/CoreRenderer.d.ts +6 -0
- package/dist/src/core/renderers/CoreRenderer.js +8 -0
- package/dist/src/core/renderers/CoreRenderer.js.map +1 -1
- package/dist/src/core/renderers/canvas/CanvasRenderer.d.ts +1 -0
- package/dist/src/core/renderers/canvas/CanvasRenderer.js +5 -0
- package/dist/src/core/renderers/canvas/CanvasRenderer.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlRenderOp.d.ts +45 -0
- package/dist/src/core/renderers/webgl/WebGlRenderOp.js +127 -0
- package/dist/src/core/renderers/webgl/WebGlRenderOp.js.map +1 -0
- package/dist/src/core/renderers/webgl/WebGlRenderer.d.ts +4 -2
- package/dist/src/core/renderers/webgl/WebGlRenderer.js +30 -22
- package/dist/src/core/renderers/webgl/WebGlRenderer.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlShaderProgram.js +2 -3
- package/dist/src/core/renderers/webgl/WebGlShaderProgram.js.map +1 -1
- package/dist/src/core/text-rendering/CanvasFont.d.ts +14 -0
- package/dist/src/core/text-rendering/CanvasFont.js +120 -0
- package/dist/src/core/text-rendering/CanvasFont.js.map +1 -0
- package/dist/src/core/text-rendering/CanvasFontHandler.d.ts +1 -1
- package/dist/src/core/text-rendering/CanvasFontHandler.js +1 -1
- package/dist/src/core/text-rendering/CanvasFontHandler.js.map +1 -1
- package/dist/src/core/text-rendering/CanvasTextRenderer.d.ts +3 -5
- package/dist/src/core/text-rendering/CanvasTextRenderer.js +16 -22
- package/dist/src/core/text-rendering/CanvasTextRenderer.js.map +1 -1
- package/dist/src/core/text-rendering/CoreFont.d.ts +33 -0
- package/dist/src/core/text-rendering/CoreFont.js +48 -0
- package/dist/src/core/text-rendering/CoreFont.js.map +1 -0
- package/dist/src/core/text-rendering/FontManager.d.ts +11 -0
- package/dist/src/core/text-rendering/FontManager.js +41 -0
- package/dist/src/core/text-rendering/FontManager.js.map +1 -0
- package/dist/src/core/text-rendering/SdfFont.d.ts +29 -0
- package/dist/src/core/text-rendering/SdfFont.js +142 -0
- package/dist/src/core/text-rendering/SdfFont.js.map +1 -0
- package/dist/src/core/text-rendering/SdfTextRenderer.d.ts +4 -6
- package/dist/src/core/text-rendering/SdfTextRenderer.js +87 -168
- package/dist/src/core/text-rendering/SdfTextRenderer.js.map +1 -1
- package/dist/src/core/text-rendering/TextGenerator.d.ts +10 -0
- package/dist/src/core/text-rendering/TextGenerator.js +36 -0
- package/dist/src/core/text-rendering/TextGenerator.js.map +1 -0
- package/dist/src/core/text-rendering/TextLayoutEngine.js +43 -12
- package/dist/src/core/text-rendering/TextLayoutEngine.js.map +1 -1
- package/dist/src/core/text-rendering/TextRenderer.d.ts +41 -27
- package/dist/src/core/text-rendering/Utils.d.ts +2 -0
- package/dist/src/core/text-rendering/Utils.js +3 -0
- package/dist/src/core/text-rendering/Utils.js.map +1 -1
- package/dist/src/main-api/Inspector.d.ts +1 -1
- package/dist/src/main-api/Inspector.js +25 -20
- package/dist/src/main-api/Inspector.js.map +1 -1
- package/dist/src/main-api/Renderer.d.ts +14 -0
- package/dist/src/main-api/Renderer.js +29 -3
- package/dist/src/main-api/Renderer.js.map +1 -1
- package/dist/tsconfig.dist.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/src/core/CoreNode.test.ts +1 -1
- package/src/core/CoreNode.ts +37 -8
- package/src/core/CoreTextNode.test.ts +350 -0
- package/src/core/CoreTextNode.ts +201 -74
- package/src/core/CoreTextureManager.ts +14 -2
- package/src/core/Stage.ts +29 -0
- package/src/core/TextureMemoryManager.test.ts +134 -0
- package/src/core/TextureMemoryManager.ts +23 -30
- package/src/core/platforms/Platform.ts +5 -0
- package/src/core/platforms/web/WebPlatform.ts +13 -0
- package/src/core/renderers/CoreRenderer.ts +10 -0
- package/src/core/renderers/canvas/CanvasRenderer.ts +6 -0
- package/src/core/renderers/webgl/WebGlRenderer.rtt.test.ts +551 -0
- package/src/core/renderers/webgl/WebGlRenderer.ts +40 -31
- package/src/core/renderers/webgl/WebGlShaderProgram.test.ts +274 -0
- package/src/core/renderers/webgl/WebGlShaderProgram.ts +7 -7
- package/src/core/text-rendering/CanvasFontHandler.ts +2 -2
- package/src/core/text-rendering/CanvasTextRenderer.ts +24 -45
- package/src/core/text-rendering/SdfTextRenderer.ts +106 -215
- package/src/core/text-rendering/TextLayoutEngine.ts +61 -28
- package/src/core/text-rendering/TextRenderer.ts +42 -33
- package/src/core/text-rendering/Utils.ts +5 -1
- package/src/core/text-rendering/tests/TextLayoutEngine.test.ts +20 -0
- package/src/main-api/Inspector.ts +25 -25
- package/src/main-api/Renderer.test.ts +153 -0
- package/src/main-api/Renderer.ts +33 -3
- package/dist/src/core/renderers/webgl/WebGlCoreShader.destroy.d.ts +0 -1
- package/dist/src/core/renderers/webgl/WebGlCoreShader.destroy.js +0 -2
- package/dist/src/core/renderers/webgl/WebGlCoreShader.destroy.js.map +0 -1
- package/src/core/renderers/webgl/SdfRenderOp.ts +0 -106
|
@@ -247,6 +247,26 @@ describe('SDF Text Utils', () => {
|
|
|
247
247
|
expect(result[0].length).toBeGreaterThan(1);
|
|
248
248
|
expect(result[0][0]?.[0]).toBe('hello world test');
|
|
249
249
|
});
|
|
250
|
+
|
|
251
|
+
it('should return non-empty output when maxWidth is smaller than glyph and suffix width', () => {
|
|
252
|
+
const result = wrapLine(
|
|
253
|
+
testMeasureText,
|
|
254
|
+
'hello',
|
|
255
|
+
'Arial',
|
|
256
|
+
5,
|
|
257
|
+
0,
|
|
258
|
+
10,
|
|
259
|
+
'...',
|
|
260
|
+
30,
|
|
261
|
+
'break-word',
|
|
262
|
+
1,
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
expect(result[0]).toHaveLength(1);
|
|
266
|
+
expect(result[0][0]?.[0]).toBe('...');
|
|
267
|
+
expect(result[0][0]?.[2]).toBe(true);
|
|
268
|
+
expect(result[1]).toBe(0);
|
|
269
|
+
});
|
|
250
270
|
});
|
|
251
271
|
|
|
252
272
|
describe('wrapText', () => {
|
|
@@ -740,12 +740,13 @@ export class Inspector {
|
|
|
740
740
|
}
|
|
741
741
|
|
|
742
742
|
createDiv(
|
|
743
|
-
|
|
743
|
+
node: CoreNode,
|
|
744
744
|
properties: CoreNodeProps | CoreTextNodeProps,
|
|
745
745
|
): HTMLElement {
|
|
746
746
|
const div = document.createElement('div');
|
|
747
747
|
div.style.position = 'absolute';
|
|
748
|
-
div.id = id.toString();
|
|
748
|
+
div.id = node.id.toString();
|
|
749
|
+
div.setAttribute('type', node.constructor.name);
|
|
749
750
|
|
|
750
751
|
// set initial properties
|
|
751
752
|
for (const key in properties) {
|
|
@@ -780,7 +781,7 @@ export class Inspector {
|
|
|
780
781
|
}
|
|
781
782
|
|
|
782
783
|
createNode(node: CoreNode): CoreNode {
|
|
783
|
-
const div = this.createDiv(node
|
|
784
|
+
const div = this.createDiv(node, node.props);
|
|
784
785
|
(div as HTMLElement & { node: CoreNode }).node = node;
|
|
785
786
|
(node as CoreNode & { div: HTMLElement }).div = div;
|
|
786
787
|
|
|
@@ -796,7 +797,7 @@ export class Inspector {
|
|
|
796
797
|
// eslint-disable-next-line
|
|
797
798
|
// @ts-ignore - textProps is a private property and keeping it that way
|
|
798
799
|
// but we need it from the inspector to set the initial properties on the div element
|
|
799
|
-
const div = this.createDiv(node
|
|
800
|
+
const div = this.createDiv(node, node.textProps);
|
|
800
801
|
(div as HTMLElement & { node: CoreNode }).node = node;
|
|
801
802
|
(node as CoreTextNode & { div: HTMLElement }).div = div;
|
|
802
803
|
|
|
@@ -897,16 +898,16 @@ export class Inspector {
|
|
|
897
898
|
};
|
|
898
899
|
// Define traps for each property in knownProperties
|
|
899
900
|
knownProperties.forEach((property) => {
|
|
900
|
-
let
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
901
|
+
let proto: CoreNode | ObjectConstructor | null = node;
|
|
902
|
+
let originalProp: PropertyDescriptor | undefined | null = Object.getOwnPropertyDescriptor(proto, property);
|
|
903
|
+
|
|
904
|
+
// Search the prototype chain for the property descriptor
|
|
905
|
+
while(originalProp === undefined) {
|
|
906
|
+
proto = Object.getPrototypeOf(proto) as ObjectConstructor;
|
|
907
|
+
if (proto === null) {
|
|
908
|
+
return;
|
|
909
|
+
}
|
|
910
|
+
originalProp = Object.getOwnPropertyDescriptor(proto, property);
|
|
910
911
|
}
|
|
911
912
|
|
|
912
913
|
if (property === 'text') {
|
|
@@ -1101,7 +1102,7 @@ export class Inspector {
|
|
|
1101
1102
|
value: any,
|
|
1102
1103
|
props: CoreNodeProps | CoreTextNodeProps,
|
|
1103
1104
|
) {
|
|
1104
|
-
if (this.root === null || value === undefined
|
|
1105
|
+
if (this.root === null || value === undefined) {
|
|
1105
1106
|
return;
|
|
1106
1107
|
}
|
|
1107
1108
|
|
|
@@ -1109,17 +1110,16 @@ export class Inspector {
|
|
|
1109
1110
|
* Special case for parent property
|
|
1110
1111
|
*/
|
|
1111
1112
|
if (property === 'parent') {
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1113
|
+
if (value) {
|
|
1114
|
+
// detect if the parent is the root node
|
|
1115
|
+
if (value.id === value.stage.root.id) {
|
|
1116
|
+
this.root.appendChild(div);
|
|
1117
|
+
} else {
|
|
1118
|
+
value.div.appendChild(div);
|
|
1119
|
+
}
|
|
1120
|
+
} else {
|
|
1121
|
+
div.parentNode?.removeChild(div);
|
|
1119
1122
|
}
|
|
1120
|
-
|
|
1121
|
-
const parent = document.getElementById(parentId.toString());
|
|
1122
|
-
parent?.appendChild(div);
|
|
1123
1123
|
return;
|
|
1124
1124
|
}
|
|
1125
1125
|
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* If not stated otherwise in this file or this component's LICENSE file the
|
|
3
|
+
* following copyright and licenses apply:
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2023 Comcast Cable Communications Management, LLC.
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the License);
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
// @vitest-environment happy-dom
|
|
21
|
+
|
|
22
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
23
|
+
import { RendererMain } from './Renderer.js';
|
|
24
|
+
import type { Platform } from '../core/platforms/Platform.js';
|
|
25
|
+
import type { Inspector } from './Inspector.js';
|
|
26
|
+
import type { CanvasRenderer } from '../core/renderers/canvas/CanvasRenderer.js';
|
|
27
|
+
import type { WebGlRenderer } from '../core/renderers/webgl/WebGlRenderer.js';
|
|
28
|
+
|
|
29
|
+
// Mock isProductionEnvironment so the Inspector gets initialized
|
|
30
|
+
vi.mock('../utils.js', async (importOriginal) => {
|
|
31
|
+
const actual = (await importOriginal()) as typeof import('../utils.js');
|
|
32
|
+
return {
|
|
33
|
+
...actual,
|
|
34
|
+
isProductionEnvironment: false,
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Mock Stage to avoid real WebGL/Canvas renderer setup
|
|
39
|
+
vi.mock('../core/Stage.js', () => {
|
|
40
|
+
const mockStage = {
|
|
41
|
+
root: {
|
|
42
|
+
id: 1,
|
|
43
|
+
children: [],
|
|
44
|
+
props: {},
|
|
45
|
+
on: vi.fn(),
|
|
46
|
+
off: vi.fn(),
|
|
47
|
+
emit: vi.fn(),
|
|
48
|
+
},
|
|
49
|
+
destroy: vi.fn(),
|
|
50
|
+
on: vi.fn(),
|
|
51
|
+
off: vi.fn(),
|
|
52
|
+
emit: vi.fn(),
|
|
53
|
+
txManager: { destroy: vi.fn() },
|
|
54
|
+
};
|
|
55
|
+
return {
|
|
56
|
+
Stage: vi.fn(() => mockStage),
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Minimal platform mock: returns a real <canvas> element so the Renderer
|
|
62
|
+
* can set its width/height and append it to the target.
|
|
63
|
+
*/
|
|
64
|
+
function makeMockPlatform() {
|
|
65
|
+
const canvas = document.createElement('canvas');
|
|
66
|
+
return vi.fn().mockReturnValue({ canvas, settings: {}, glw: null });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Convenience: construct RendererMain with the minimum required settings. */
|
|
70
|
+
function makeRenderer(
|
|
71
|
+
target: HTMLElement,
|
|
72
|
+
extra: Partial<{
|
|
73
|
+
inspector: typeof Inspector | false;
|
|
74
|
+
}> = {},
|
|
75
|
+
) {
|
|
76
|
+
const MockPlatform = makeMockPlatform();
|
|
77
|
+
return new RendererMain(
|
|
78
|
+
{
|
|
79
|
+
appWidth: 1920,
|
|
80
|
+
appHeight: 1080,
|
|
81
|
+
inspector: extra.inspector ?? false,
|
|
82
|
+
platform: MockPlatform as unknown as typeof Platform,
|
|
83
|
+
renderEngine: {} as unknown as
|
|
84
|
+
| typeof CanvasRenderer
|
|
85
|
+
| typeof WebGlRenderer,
|
|
86
|
+
},
|
|
87
|
+
target,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
describe('RendererMain.close()', () => {
|
|
92
|
+
let target: HTMLDivElement;
|
|
93
|
+
|
|
94
|
+
beforeEach(() => {
|
|
95
|
+
target = document.createElement('div');
|
|
96
|
+
document.body.appendChild(target);
|
|
97
|
+
vi.clearAllMocks();
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
afterEach(() => {
|
|
101
|
+
target.remove();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('should call inspector.destroy() when close() is called', () => {
|
|
105
|
+
const inspectorDestroy = vi.fn();
|
|
106
|
+
const MockInspector = vi.fn(() => ({ destroy: inspectorDestroy }));
|
|
107
|
+
|
|
108
|
+
const renderer = makeRenderer(target, {
|
|
109
|
+
inspector: MockInspector as unknown as typeof Inspector,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
renderer.close();
|
|
113
|
+
|
|
114
|
+
expect(inspectorDestroy).toHaveBeenCalledOnce();
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('should call stage.destroy() when close() is called', async () => {
|
|
118
|
+
const { Stage } = await import('../core/Stage.js');
|
|
119
|
+
const renderer = makeRenderer(target);
|
|
120
|
+
|
|
121
|
+
const mockStageInstance = vi.mocked(Stage).mock.results[0]?.value as {
|
|
122
|
+
destroy: ReturnType<typeof vi.fn>;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
renderer.close();
|
|
126
|
+
|
|
127
|
+
expect(mockStageInstance?.destroy).toHaveBeenCalledOnce();
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('should remove the canvas from the DOM when close() is called', () => {
|
|
131
|
+
const renderer = makeRenderer(target);
|
|
132
|
+
const canvas = renderer.canvas;
|
|
133
|
+
|
|
134
|
+
expect(target.contains(canvas)).toBe(true);
|
|
135
|
+
|
|
136
|
+
renderer.close();
|
|
137
|
+
|
|
138
|
+
expect(document.contains(canvas)).toBe(false);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('should not throw when close() is called a second time', () => {
|
|
142
|
+
const MockInspector = vi.fn(() => ({ destroy: vi.fn() }));
|
|
143
|
+
|
|
144
|
+
const renderer = makeRenderer(target, {
|
|
145
|
+
inspector: MockInspector as unknown as typeof Inspector,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
renderer.close();
|
|
149
|
+
|
|
150
|
+
// inspector is set to null after close(); the ?. guard must handle it
|
|
151
|
+
expect(() => renderer.close()).not.toThrow();
|
|
152
|
+
});
|
|
153
|
+
});
|
package/src/main-api/Renderer.ts
CHANGED
|
@@ -533,7 +533,7 @@ export class RendererMain extends EventEmitter {
|
|
|
533
533
|
boundsMargin: settings.boundsMargin || 0,
|
|
534
534
|
deviceLogicalPixelRatio: settings.deviceLogicalPixelRatio || 1,
|
|
535
535
|
devicePhysicalPixelRatio:
|
|
536
|
-
settings.devicePhysicalPixelRatio ||
|
|
536
|
+
settings.devicePhysicalPixelRatio || this.windowDevicePixelRatio() || 1,
|
|
537
537
|
clearColor: settings.clearColor ?? 0x00000000,
|
|
538
538
|
fpsUpdateInterval: settings.fpsUpdateInterval || 0,
|
|
539
539
|
enableClear: settings.enableClear ?? true,
|
|
@@ -582,8 +582,10 @@ export class RendererMain extends EventEmitter {
|
|
|
582
582
|
this.canvas.width = deviceLogicalWidth * devicePhysicalPixelRatio;
|
|
583
583
|
this.canvas.height = deviceLogicalHeight * devicePhysicalPixelRatio;
|
|
584
584
|
|
|
585
|
-
this.canvas.style
|
|
586
|
-
|
|
585
|
+
if (this.canvas.style) {
|
|
586
|
+
this.canvas.style.width = `${deviceLogicalWidth}px`;
|
|
587
|
+
this.canvas.style.height = `${deviceLogicalHeight}px`;
|
|
588
|
+
}
|
|
587
589
|
|
|
588
590
|
// Initialize the stage
|
|
589
591
|
this.stage = new Stage({
|
|
@@ -1027,4 +1029,32 @@ export class RendererMain extends EventEmitter {
|
|
|
1027
1029
|
this.stage.options.targetFPS = fps > 0 ? fps : 0;
|
|
1028
1030
|
this.stage.updateTargetFrameTime();
|
|
1029
1031
|
}
|
|
1032
|
+
|
|
1033
|
+
private windowDevicePixelRatio() {
|
|
1034
|
+
return typeof window !== 'undefined' ? window.devicePixelRatio : undefined;
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
/**
|
|
1038
|
+
* Close and destroy the renderer, releasing all resources.
|
|
1039
|
+
*
|
|
1040
|
+
* @remarks
|
|
1041
|
+
* This method performs a full teardown of the renderer:
|
|
1042
|
+
* - Stops the platform render loop
|
|
1043
|
+
* - Destroys all scene nodes (including text node font resources)
|
|
1044
|
+
* - Releases all texture memory and GPU resources
|
|
1045
|
+
* - Terminates image worker threads
|
|
1046
|
+
* - Removes the canvas element from the target div
|
|
1047
|
+
* - Destroys the inspector if active
|
|
1048
|
+
*/
|
|
1049
|
+
close(): void {
|
|
1050
|
+
// Destroy the inspector first
|
|
1051
|
+
this.inspector?.destroy();
|
|
1052
|
+
this.inspector = null;
|
|
1053
|
+
|
|
1054
|
+
// Destroy the stage (stops loop, destroys nodes, releases textures/GPU)
|
|
1055
|
+
this.stage.destroy();
|
|
1056
|
+
|
|
1057
|
+
// Remove the canvas from the DOM
|
|
1058
|
+
this.canvas.remove();
|
|
1059
|
+
}
|
|
1030
1060
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WebGlCoreShader.destroy.js","sourceRoot":"","sources":["../../../../../src/core/renderers/webgl/WebGlCoreShader.destroy.ts"],"names":[],"mappings":""}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* If not stated otherwise in this file or this component's LICENSE file the
|
|
3
|
-
* following copyright and licenses apply:
|
|
4
|
-
*
|
|
5
|
-
* Copyright 2023 Comcast Cable Communications Management, LLC.
|
|
6
|
-
*
|
|
7
|
-
* Licensed under the Apache License, Version 2.0 (the License);
|
|
8
|
-
* you may not use this file except in compliance with the License.
|
|
9
|
-
* You may obtain a copy of the License at
|
|
10
|
-
*
|
|
11
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
-
*
|
|
13
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
-
* See the License for the specific language governing permissions and
|
|
17
|
-
* limitations under the License.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
import { CoreRenderOp } from '../CoreRenderOp.js';
|
|
21
|
-
import type { WebGlCtxTexture } from './WebGlCtxTexture.js';
|
|
22
|
-
import type { WebGlRenderer } from './WebGlRenderer.js';
|
|
23
|
-
import type { BufferCollection } from './internal/BufferCollection.js';
|
|
24
|
-
import type { WebGlShaderNode } from './WebGlShaderNode.js';
|
|
25
|
-
import type { RectWithValid } from '../../lib/utils.js';
|
|
26
|
-
import type { Dimensions } from '../../../common/CommonTypes.js';
|
|
27
|
-
import type { Stage } from '../../Stage.js';
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Can render multiple quads with multiple textures (up to vertex shader texture limit)
|
|
31
|
-
*
|
|
32
|
-
*/
|
|
33
|
-
export class SdfRenderOp extends CoreRenderOp {
|
|
34
|
-
public numQuads = 0;
|
|
35
|
-
public readonly isCoreNode = false as const;
|
|
36
|
-
public renderOpTextures: WebGlCtxTexture[] = [];
|
|
37
|
-
public time: number = 0;
|
|
38
|
-
readonly stage: Stage;
|
|
39
|
-
|
|
40
|
-
constructor(
|
|
41
|
-
readonly renderer: WebGlRenderer,
|
|
42
|
-
readonly shader: WebGlShaderNode,
|
|
43
|
-
readonly sdfShaderProps: Record<string, unknown>,
|
|
44
|
-
readonly quadBufferCollection: BufferCollection,
|
|
45
|
-
readonly worldAlpha: number,
|
|
46
|
-
readonly clippingRect: RectWithValid,
|
|
47
|
-
readonly w: number,
|
|
48
|
-
readonly h: number,
|
|
49
|
-
readonly rtt: boolean,
|
|
50
|
-
readonly parentHasRenderTexture: boolean,
|
|
51
|
-
readonly framebufferDimensions: Dimensions | null,
|
|
52
|
-
) {
|
|
53
|
-
super();
|
|
54
|
-
this.stage = renderer.stage;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
addTexture(texture: WebGlCtxTexture): number {
|
|
58
|
-
const { renderOpTextures } = this;
|
|
59
|
-
const length = renderOpTextures.length;
|
|
60
|
-
|
|
61
|
-
// We only support 1 texture (atlas) for SDF for now, but following the pattern
|
|
62
|
-
for (let i = 0; i < length; i++) {
|
|
63
|
-
if (renderOpTextures[i] === texture) {
|
|
64
|
-
return i;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
renderOpTextures.push(texture);
|
|
69
|
-
return length;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
draw() {
|
|
73
|
-
const { glw, stage } = this.renderer;
|
|
74
|
-
const canvas = stage.platform!.canvas!;
|
|
75
|
-
|
|
76
|
-
stage.shManager.useShader(this.shader.program);
|
|
77
|
-
this.shader.program.bindRenderOp(this);
|
|
78
|
-
|
|
79
|
-
// Clipping
|
|
80
|
-
if (this.clippingRect.valid === true) {
|
|
81
|
-
const pixelRatio = this.parentHasRenderTexture ? 1 : stage.pixelRatio;
|
|
82
|
-
const clipX = Math.round(this.clippingRect.x * pixelRatio);
|
|
83
|
-
const clipWidth = Math.round(this.clippingRect.w * pixelRatio);
|
|
84
|
-
const clipHeight = Math.round(this.clippingRect.h * pixelRatio);
|
|
85
|
-
let clipY = Math.round(
|
|
86
|
-
canvas.height - clipHeight - this.clippingRect.y * pixelRatio,
|
|
87
|
-
);
|
|
88
|
-
// if parent has render texture, we need to adjust the scissor rect
|
|
89
|
-
// to be relative to the parent's framebuffer
|
|
90
|
-
if (this.parentHasRenderTexture) {
|
|
91
|
-
clipY = this.framebufferDimensions
|
|
92
|
-
? this.framebufferDimensions.h - this.h
|
|
93
|
-
: 0;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
glw.setScissorTest(true);
|
|
97
|
-
glw.scissor(clipX, clipY, clipWidth, clipHeight);
|
|
98
|
-
} else {
|
|
99
|
-
glw.setScissorTest(false);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// SDF rendering uses drawArrays with explicit triangle vertices (6 vertices per quad)
|
|
103
|
-
// Note: buffers should be bound by bindRenderOp -> bindBufferCollection
|
|
104
|
-
glw.drawArrays(glw.TRIANGLES, 0, 6 * this.numQuads);
|
|
105
|
-
}
|
|
106
|
-
}
|