@lightningjs/renderer 0.9.1 → 0.9.3
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/exports/index.d.ts +3 -0
- package/dist/{src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.js → exports/index.js} +4 -11
- package/dist/exports/index.js.map +1 -0
- package/dist/src/common/IAnimationController.d.ts +58 -1
- package/dist/src/common/IAnimationController.js +0 -18
- package/dist/src/common/IAnimationController.js.map +1 -1
- package/dist/src/core/CoreNode.js +40 -0
- package/dist/src/core/CoreNode.js.map +1 -1
- package/dist/src/core/CoreTextureManager.d.ts +35 -0
- package/dist/src/core/CoreTextureManager.js +1 -1
- package/dist/src/core/CoreTextureManager.js.map +1 -1
- package/dist/src/core/TextureList.js +34 -0
- package/dist/src/core/TextureList.js.map +1 -0
- package/dist/src/core/animations/CoreAnimation.d.ts +2 -2
- package/dist/src/core/animations/CoreAnimation.js +33 -10
- package/dist/src/core/animations/CoreAnimation.js.map +1 -1
- package/dist/src/core/animations/CoreAnimationController.d.ts +8 -12
- package/dist/src/core/animations/CoreAnimationController.js +42 -46
- package/dist/src/core/animations/CoreAnimationController.js.map +1 -1
- package/dist/src/core/lib/ImageWorker.d.ts +0 -1
- package/dist/src/core/lib/ImageWorker.js +8 -10
- package/dist/src/core/lib/ImageWorker.js.map +1 -1
- package/dist/src/core/lib/utils.d.ts +1 -0
- package/dist/src/core/lib/utils.js +20 -0
- package/dist/src/core/lib/utils.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +25 -0
- package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +1 -1
- package/dist/src/core/renderers/webgl/newShader/effectsMock.d.ts +1 -0
- package/dist/src/core/renderers/webgl/newShader/effectsMock.js +36 -0
- package/dist/src/core/renderers/webgl/newShader/effectsMock.js.map +1 -0
- package/dist/src/core/renderers/webgl/shaders/effects/BorderEffect.js +2 -1
- package/dist/src/core/renderers/webgl/shaders/effects/BorderEffect.js.map +1 -1
- package/dist/src/core/textures/ImageTexture.d.ts +5 -1
- package/dist/src/core/textures/ImageTexture.js +20 -9
- package/dist/src/core/textures/ImageTexture.js.map +1 -1
- package/dist/src/core/utils.js +1 -6
- package/dist/src/core/utils.js.map +1 -1
- package/dist/src/main-api/INode.d.ts +1 -1
- package/dist/src/main-api/Renderer.d.ts +314 -0
- package/dist/src/main-api/Renderer.js +387 -0
- package/dist/src/main-api/Renderer.js.map +1 -0
- package/dist/src/main-api/utils.d.ts +2 -0
- package/dist/src/main-api/utils.js +34 -0
- package/dist/src/main-api/utils.js.map +1 -0
- package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.d.ts +8 -4
- package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.js +53 -24
- package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.js.map +1 -1
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js +6 -0
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js.map +1 -1
- package/dist/src/render-drivers/utils.js +6 -1
- package/dist/src/render-drivers/utils.js.map +1 -1
- package/dist/tsconfig.dist.tsbuildinfo +1 -1
- package/{dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.js → exports/index.ts} +4 -14
- package/package.json +1 -1
- package/src/common/IAnimationController.ts +60 -1
- package/src/core/CoreNode.ts +45 -0
- package/src/core/CoreTextureManager.ts +40 -1
- package/src/core/animations/CoreAnimation.ts +35 -11
- package/src/core/animations/CoreAnimationController.ts +48 -53
- package/src/core/lib/ImageWorker.ts +10 -13
- package/src/core/lib/utils.ts +25 -0
- package/src/core/renderers/webgl/WebGlCoreRenderer.ts +27 -0
- package/src/core/renderers/webgl/shaders/effects/BorderEffect.ts +2 -1
- package/src/core/textures/ImageTexture.ts +26 -9
- package/src/core/utils.ts +1 -7
- package/src/main-api/INode.ts +1 -1
- package/src/render-drivers/threadx/ThreadXMainAnimationController.ts +63 -27
- package/src/render-drivers/threadx/worker/ThreadXRendererNode.ts +6 -0
- package/src/render-drivers/utils.ts +6 -1
- package/dist/src/core/lib/WebGlContext.d.ts +0 -414
- package/dist/src/core/lib/WebGlContext.js +0 -640
- package/dist/src/core/lib/WebGlContext.js.map +0 -1
- package/dist/src/core/scene/Scene.d.ts +0 -59
- package/dist/src/core/scene/Scene.js +0 -106
- package/dist/src/core/scene/Scene.js.map +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.d.ts +0 -8
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.js.map +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.d.ts +0 -19
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.js +0 -84
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.js.map +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.d.ts +0 -8
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.js +0 -40
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.js.map +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.d.ts +0 -2
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.js +0 -41
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.js.map +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.d.ts +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.js +0 -4
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.js.map +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.js +0 -2
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.js.map +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.d.ts +0 -20
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.js +0 -55
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.js.map +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.d.ts +0 -9
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.js.map +0 -1
- /package/dist/src/core/{text-rendering/renderers/SdfTextRenderer/internal/layoutText2.d.ts → TextureList.d.ts} +0 -0
|
@@ -417,7 +417,7 @@ export interface INodeWritableProps {
|
|
|
417
417
|
* The data stored can only be of type string, number or boolean.
|
|
418
418
|
*/
|
|
419
419
|
export type CustomDataMap = {
|
|
420
|
-
[key: string]: string | number | boolean;
|
|
420
|
+
[key: string]: string | number | boolean | undefined;
|
|
421
421
|
};
|
|
422
422
|
export type INodeAnimatableProps = {
|
|
423
423
|
[Key in keyof INodeWritableProps as NonNullable<INodeWritableProps[Key]> extends number ? Key : never]: number;
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import type { ShaderMap } from '../core/CoreShaderManager.js';
|
|
2
|
+
import type { ExtractProps, TextureTypeMap, TextureMap } from '../core/CoreTextureManager.js';
|
|
3
|
+
import { EventEmitter } from '../common/EventEmitter.js';
|
|
4
|
+
import { Stage } from '../core/Stage.js';
|
|
5
|
+
import { CoreNode, type CoreNodeWritableProps } from '../core/CoreNode.js';
|
|
6
|
+
import { CoreTextNode, type CoreTextNodeWritableProps } from '../core/CoreTextNode.js';
|
|
7
|
+
import type { TextureMemoryManagerSettings } from '../core/TextureMemoryManager.js';
|
|
8
|
+
/**
|
|
9
|
+
* An immutable reference to a specific Shader type
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* See {@link ShaderRef} for more details.
|
|
13
|
+
*/
|
|
14
|
+
export interface SpecificShaderRef<ShType extends keyof ShaderMap> {
|
|
15
|
+
readonly descType: 'shader';
|
|
16
|
+
readonly shType: ShType;
|
|
17
|
+
readonly props: ExtractProps<ShaderMap[ShType]>;
|
|
18
|
+
}
|
|
19
|
+
type MapShaderRefs<ShType extends keyof ShaderMap> = ShType extends keyof ShaderMap ? SpecificShaderRef<ShType> : never;
|
|
20
|
+
/**
|
|
21
|
+
* An immutable reference to a Shader
|
|
22
|
+
*
|
|
23
|
+
* @remarks
|
|
24
|
+
* This structure should only be created by the RendererMain's `createShader`
|
|
25
|
+
* method. The structure is immutable and should not be modified once created.
|
|
26
|
+
*
|
|
27
|
+
* A `ShaderRef` exists in the Main API Space and is used to point to an actual
|
|
28
|
+
* `Shader` instance in the Core API Space. The `ShaderRef` is used to
|
|
29
|
+
* communicate with the Core API Space to create, load, and destroy the
|
|
30
|
+
* `Shader` instance.
|
|
31
|
+
*
|
|
32
|
+
* This type is technically a discriminated union of all possible shader types.
|
|
33
|
+
* If you'd like to represent a specific shader type, you can use the
|
|
34
|
+
* `SpecificShaderRef` generic type.
|
|
35
|
+
*/
|
|
36
|
+
export type ShaderRef = MapShaderRefs<keyof ShaderMap>;
|
|
37
|
+
/**
|
|
38
|
+
* Configuration settings for {@link RendererMain}
|
|
39
|
+
*/
|
|
40
|
+
export interface RendererMainSettings {
|
|
41
|
+
/**
|
|
42
|
+
* Authored logical pixel width of the application
|
|
43
|
+
*
|
|
44
|
+
* @defaultValue `1920`
|
|
45
|
+
*/
|
|
46
|
+
appWidth?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Authored logical pixel height of the application
|
|
49
|
+
*
|
|
50
|
+
* @defaultValue `1080`
|
|
51
|
+
*/
|
|
52
|
+
appHeight?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Texture Memory Manager Settings
|
|
55
|
+
*/
|
|
56
|
+
textureMemory?: Partial<TextureMemoryManagerSettings>;
|
|
57
|
+
/**
|
|
58
|
+
* Bounds margin to extend the boundary in which a CoreNode is added as Quad.
|
|
59
|
+
*/
|
|
60
|
+
boundsMargin?: number | [number, number, number, number];
|
|
61
|
+
/**
|
|
62
|
+
* Factor to convert app-authored logical coorindates to device logical coordinates
|
|
63
|
+
*
|
|
64
|
+
* @remarks
|
|
65
|
+
* This value allows auto-scaling to support larger/small resolutions than the
|
|
66
|
+
* app was authored for.
|
|
67
|
+
*
|
|
68
|
+
* If the app was authored for 1920x1080 and this value is 2, the app's canvas
|
|
69
|
+
* will be rendered at 3840x2160 logical pixels.
|
|
70
|
+
*
|
|
71
|
+
* Likewise, if the app was authored for 1920x1080 and this value is 0.66667,
|
|
72
|
+
* the app's canvas will be rendered at 1280x720 logical pixels.
|
|
73
|
+
*
|
|
74
|
+
* @defaultValue `1`
|
|
75
|
+
*/
|
|
76
|
+
deviceLogicalPixelRatio?: number;
|
|
77
|
+
/**
|
|
78
|
+
* Factor to convert device logical coordinates to device physical coordinates
|
|
79
|
+
*
|
|
80
|
+
* @remarks
|
|
81
|
+
* This value allows auto-scaling to support devices with different pixel densities.
|
|
82
|
+
*
|
|
83
|
+
* This controls the number of physical pixels that are used to render each logical
|
|
84
|
+
* pixel. For example, if the device has a pixel density of 2, each logical pixel
|
|
85
|
+
* will be rendered using 2x2 physical pixels.
|
|
86
|
+
*
|
|
87
|
+
* By default, it will be set to `window.devicePixelRatio` which is the pixel
|
|
88
|
+
* density of the device the app is running on reported by the browser.
|
|
89
|
+
*
|
|
90
|
+
* @defaultValue `window.devicePixelRatio`
|
|
91
|
+
*/
|
|
92
|
+
devicePhysicalPixelRatio?: number;
|
|
93
|
+
/**
|
|
94
|
+
* RGBA encoded number of the background to use
|
|
95
|
+
*
|
|
96
|
+
* @defaultValue `0x00000000`
|
|
97
|
+
*/
|
|
98
|
+
clearColor?: number;
|
|
99
|
+
/**
|
|
100
|
+
* Interval in milliseconds to receive FPS updates
|
|
101
|
+
*
|
|
102
|
+
* @remarks
|
|
103
|
+
* If set to `0`, FPS updates will be disabled.
|
|
104
|
+
*
|
|
105
|
+
* @defaultValue `0` (disabled)
|
|
106
|
+
*/
|
|
107
|
+
fpsUpdateInterval?: number;
|
|
108
|
+
/**
|
|
109
|
+
* Include context call (i.e. WebGL) information in FPS updates
|
|
110
|
+
*
|
|
111
|
+
* @remarks
|
|
112
|
+
* When enabled the number of calls to each context method over the
|
|
113
|
+
* `fpsUpdateInterval` will be included in the FPS update payload's
|
|
114
|
+
* `contextSpyData` property.
|
|
115
|
+
*
|
|
116
|
+
* Enabling the context spy has a serious impact on performance so only use it
|
|
117
|
+
* when you need to extract context call information.
|
|
118
|
+
*
|
|
119
|
+
* @defaultValue `false` (disabled)
|
|
120
|
+
*/
|
|
121
|
+
enableContextSpy?: boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Number or Image Workers to use
|
|
124
|
+
*
|
|
125
|
+
* @remarks
|
|
126
|
+
* On devices with multiple cores, this can be used to improve image loading
|
|
127
|
+
* as well as reduce the impact of image loading on the main thread.
|
|
128
|
+
* Set to 0 to disable image workers.
|
|
129
|
+
*
|
|
130
|
+
* @defaultValue `2`
|
|
131
|
+
*/
|
|
132
|
+
numImageWorkers?: number;
|
|
133
|
+
/**
|
|
134
|
+
* Enable inspector
|
|
135
|
+
*
|
|
136
|
+
* @remarks
|
|
137
|
+
* When enabled the renderer will spawn a inspector. The inspector will
|
|
138
|
+
* replicate the state of the Nodes created in the renderer and allow
|
|
139
|
+
* inspection of the state of the nodes.
|
|
140
|
+
*
|
|
141
|
+
* @defaultValue `false` (disabled)
|
|
142
|
+
*/
|
|
143
|
+
enableInspector?: boolean;
|
|
144
|
+
/**
|
|
145
|
+
* Renderer mode
|
|
146
|
+
*/
|
|
147
|
+
renderMode?: 'webgl' | 'canvas';
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The Renderer Main API
|
|
151
|
+
*
|
|
152
|
+
* @remarks
|
|
153
|
+
* This is the primary class used to configure and operate the Renderer.
|
|
154
|
+
*
|
|
155
|
+
* It is used to create and destroy Nodes, as well as Texture and Shader
|
|
156
|
+
* references.
|
|
157
|
+
*
|
|
158
|
+
* Example:
|
|
159
|
+
* ```ts
|
|
160
|
+
* import { RendererMain, MainCoreDriver } from '@lightningjs/renderer';
|
|
161
|
+
*
|
|
162
|
+
* // Initialize the Renderer
|
|
163
|
+
* const renderer = new RendererMain(
|
|
164
|
+
* {
|
|
165
|
+
* appWidth: 1920,
|
|
166
|
+
* appHeight: 1080
|
|
167
|
+
* },
|
|
168
|
+
* 'app',
|
|
169
|
+
* new MainCoreDriver(),
|
|
170
|
+
* );
|
|
171
|
+
* ```
|
|
172
|
+
*
|
|
173
|
+
* ## Events
|
|
174
|
+
* - `fpsUpdate`
|
|
175
|
+
* - Emitted every `fpsUpdateInterval` milliseconds with the current FPS
|
|
176
|
+
* - `frameTick`
|
|
177
|
+
* - Emitted every frame tick
|
|
178
|
+
* - `idle`
|
|
179
|
+
* - Emitted when the renderer is idle (no changes to the scene
|
|
180
|
+
* graph/animations running)
|
|
181
|
+
* - `criticalCleanup`
|
|
182
|
+
* - Emitted when the Texture Memory Manager Cleanup process is triggered
|
|
183
|
+
* - Payload: { memUsed: number, criticalThreshold: number }
|
|
184
|
+
* - `memUsed` - The amount of memory (in bytes) used by textures before the
|
|
185
|
+
* cleanup process
|
|
186
|
+
* - `criticalThreshold` - The critical threshold (in bytes)
|
|
187
|
+
* - `criticalCleanupFailed`
|
|
188
|
+
* - Emitted when the Texture Memory Manager Cleanup process is unable to free
|
|
189
|
+
* up enough texture memory to reach below the critical threshold.
|
|
190
|
+
* This can happen when there is not enough non-renderable textures to
|
|
191
|
+
* free up.
|
|
192
|
+
* - Payload (object with keys):
|
|
193
|
+
* - `memUsed` - The amount of memory (in bytes) used by textures after
|
|
194
|
+
* the cleanup process
|
|
195
|
+
* - `criticalThreshold` - The critical threshold (in bytes)
|
|
196
|
+
*/
|
|
197
|
+
export declare class RendererMain extends EventEmitter {
|
|
198
|
+
readonly root: CoreNode;
|
|
199
|
+
readonly canvas: HTMLCanvasElement;
|
|
200
|
+
readonly settings: Readonly<Required<RendererMainSettings>>;
|
|
201
|
+
readonly stage: Stage;
|
|
202
|
+
private inspector;
|
|
203
|
+
/**
|
|
204
|
+
* Constructs a new Renderer instance
|
|
205
|
+
*
|
|
206
|
+
* @param settings Renderer settings
|
|
207
|
+
* @param target Element ID or HTMLElement to insert the canvas into
|
|
208
|
+
* @param driver Core Driver to use
|
|
209
|
+
*/
|
|
210
|
+
constructor(settings: RendererMainSettings, target: string | HTMLElement);
|
|
211
|
+
/**
|
|
212
|
+
* Create a new scene graph node
|
|
213
|
+
*
|
|
214
|
+
* @remarks
|
|
215
|
+
* A node is the main graphical building block of the Renderer scene graph. It
|
|
216
|
+
* can be a container for other nodes, or it can be a leaf node that renders a
|
|
217
|
+
* solid color, gradient, image, or specific texture, using a specific shader.
|
|
218
|
+
*
|
|
219
|
+
* To create a text node, see {@link createTextNode}.
|
|
220
|
+
*
|
|
221
|
+
* See {@link CoreNode} for more details.
|
|
222
|
+
*
|
|
223
|
+
* @param props
|
|
224
|
+
* @returns
|
|
225
|
+
*/
|
|
226
|
+
createNode(props: Partial<CoreNodeWritableProps>): CoreNode;
|
|
227
|
+
/**
|
|
228
|
+
* Create a new scene graph text node
|
|
229
|
+
*
|
|
230
|
+
* @remarks
|
|
231
|
+
* A text node is the second graphical building block of the Renderer scene
|
|
232
|
+
* graph. It renders text using a specific text renderer that is automatically
|
|
233
|
+
* chosen based on the font requested and what type of fonts are installed
|
|
234
|
+
* into an app.
|
|
235
|
+
*
|
|
236
|
+
* See {@link ITextNode} for more details.
|
|
237
|
+
*
|
|
238
|
+
* @param props
|
|
239
|
+
* @returns
|
|
240
|
+
*/
|
|
241
|
+
createTextNode(props: Partial<CoreTextNodeWritableProps>): CoreTextNode;
|
|
242
|
+
/**
|
|
243
|
+
* Resolves the default property values for a Node
|
|
244
|
+
*
|
|
245
|
+
* @remarks
|
|
246
|
+
* This method is used internally by the RendererMain to resolve the default
|
|
247
|
+
* property values for a Node. It is exposed publicly so that it can be used
|
|
248
|
+
* by Core Driver implementations.
|
|
249
|
+
*
|
|
250
|
+
* @param props
|
|
251
|
+
* @returns
|
|
252
|
+
*/
|
|
253
|
+
resolveNodeDefaults(props: Partial<CoreNodeWritableProps>): CoreNodeWritableProps;
|
|
254
|
+
/**
|
|
255
|
+
* Destroy a node
|
|
256
|
+
*
|
|
257
|
+
* @remarks
|
|
258
|
+
* This method destroys a node
|
|
259
|
+
*
|
|
260
|
+
* @param node
|
|
261
|
+
* @returns
|
|
262
|
+
*/
|
|
263
|
+
destroyNode(node: CoreNode): void;
|
|
264
|
+
/**
|
|
265
|
+
* Create a new texture reference
|
|
266
|
+
*
|
|
267
|
+
* @remarks
|
|
268
|
+
* This method creates a new reference to a texture. The texture is not
|
|
269
|
+
* loaded until it is used on a node.
|
|
270
|
+
*
|
|
271
|
+
* It can be assigned to a node's `texture` property, or it can be used
|
|
272
|
+
* when creating a SubTexture.
|
|
273
|
+
*
|
|
274
|
+
* @param textureType
|
|
275
|
+
* @param props
|
|
276
|
+
* @param options
|
|
277
|
+
* @returns
|
|
278
|
+
*/
|
|
279
|
+
createTexture<TxType extends keyof TextureTypeMap>(textureType: TxType, props: ExtractProps<TextureTypeMap[TxType]>): TextureMap[TxType];
|
|
280
|
+
/**
|
|
281
|
+
* Create a new shader reference
|
|
282
|
+
*
|
|
283
|
+
* @remarks
|
|
284
|
+
* This method creates a new reference to a shader. The shader is not
|
|
285
|
+
* loaded until it is used on a Node.
|
|
286
|
+
*
|
|
287
|
+
* It can be assigned to a Node's `shader` property.
|
|
288
|
+
*
|
|
289
|
+
* @param shaderType
|
|
290
|
+
* @param props
|
|
291
|
+
* @returns
|
|
292
|
+
*/
|
|
293
|
+
createShader<ShType extends keyof ShaderMap>(shaderType: ShType, props?: ExtractProps<ShaderMap[ShType]>): SpecificShaderRef<ShType>;
|
|
294
|
+
/**
|
|
295
|
+
* Get a Node by its ID
|
|
296
|
+
*
|
|
297
|
+
* @param id
|
|
298
|
+
* @returns
|
|
299
|
+
*/
|
|
300
|
+
getNodeById(id: number): CoreNode | null;
|
|
301
|
+
toggleFreeze(): void;
|
|
302
|
+
advanceFrame(): void;
|
|
303
|
+
/**
|
|
304
|
+
* Re-render the current frame without advancing any running animations.
|
|
305
|
+
*
|
|
306
|
+
* @remarks
|
|
307
|
+
* Any state changes will be reflected in the re-rendered frame. Useful for
|
|
308
|
+
* debugging.
|
|
309
|
+
*
|
|
310
|
+
* May not do anything if the render loop is running on a separate worker.
|
|
311
|
+
*/
|
|
312
|
+
rerender(): void;
|
|
313
|
+
}
|
|
314
|
+
export {};
|
|
@@ -0,0 +1,387 @@
|
|
|
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
|
+
import { EventEmitter } from '../common/EventEmitter.js';
|
|
20
|
+
import { Inspector } from './Inspector.js';
|
|
21
|
+
import { santizeCustomDataMap } from './utils.js';
|
|
22
|
+
import { assertTruthy, isProductionEnvironment } from '../utils.js';
|
|
23
|
+
import { Stage, } from '../core/Stage.js';
|
|
24
|
+
import { getNewId } from '../utils.js';
|
|
25
|
+
import { CoreNode } from '../core/CoreNode.js';
|
|
26
|
+
import { CoreTextNode, } from '../core/CoreTextNode.js';
|
|
27
|
+
/**
|
|
28
|
+
* The Renderer Main API
|
|
29
|
+
*
|
|
30
|
+
* @remarks
|
|
31
|
+
* This is the primary class used to configure and operate the Renderer.
|
|
32
|
+
*
|
|
33
|
+
* It is used to create and destroy Nodes, as well as Texture and Shader
|
|
34
|
+
* references.
|
|
35
|
+
*
|
|
36
|
+
* Example:
|
|
37
|
+
* ```ts
|
|
38
|
+
* import { RendererMain, MainCoreDriver } from '@lightningjs/renderer';
|
|
39
|
+
*
|
|
40
|
+
* // Initialize the Renderer
|
|
41
|
+
* const renderer = new RendererMain(
|
|
42
|
+
* {
|
|
43
|
+
* appWidth: 1920,
|
|
44
|
+
* appHeight: 1080
|
|
45
|
+
* },
|
|
46
|
+
* 'app',
|
|
47
|
+
* new MainCoreDriver(),
|
|
48
|
+
* );
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* ## Events
|
|
52
|
+
* - `fpsUpdate`
|
|
53
|
+
* - Emitted every `fpsUpdateInterval` milliseconds with the current FPS
|
|
54
|
+
* - `frameTick`
|
|
55
|
+
* - Emitted every frame tick
|
|
56
|
+
* - `idle`
|
|
57
|
+
* - Emitted when the renderer is idle (no changes to the scene
|
|
58
|
+
* graph/animations running)
|
|
59
|
+
* - `criticalCleanup`
|
|
60
|
+
* - Emitted when the Texture Memory Manager Cleanup process is triggered
|
|
61
|
+
* - Payload: { memUsed: number, criticalThreshold: number }
|
|
62
|
+
* - `memUsed` - The amount of memory (in bytes) used by textures before the
|
|
63
|
+
* cleanup process
|
|
64
|
+
* - `criticalThreshold` - The critical threshold (in bytes)
|
|
65
|
+
* - `criticalCleanupFailed`
|
|
66
|
+
* - Emitted when the Texture Memory Manager Cleanup process is unable to free
|
|
67
|
+
* up enough texture memory to reach below the critical threshold.
|
|
68
|
+
* This can happen when there is not enough non-renderable textures to
|
|
69
|
+
* free up.
|
|
70
|
+
* - Payload (object with keys):
|
|
71
|
+
* - `memUsed` - The amount of memory (in bytes) used by textures after
|
|
72
|
+
* the cleanup process
|
|
73
|
+
* - `criticalThreshold` - The critical threshold (in bytes)
|
|
74
|
+
*/
|
|
75
|
+
export class RendererMain extends EventEmitter {
|
|
76
|
+
root;
|
|
77
|
+
canvas;
|
|
78
|
+
settings;
|
|
79
|
+
stage;
|
|
80
|
+
inspector = null;
|
|
81
|
+
/**
|
|
82
|
+
* Constructs a new Renderer instance
|
|
83
|
+
*
|
|
84
|
+
* @param settings Renderer settings
|
|
85
|
+
* @param target Element ID or HTMLElement to insert the canvas into
|
|
86
|
+
* @param driver Core Driver to use
|
|
87
|
+
*/
|
|
88
|
+
constructor(settings, target) {
|
|
89
|
+
super();
|
|
90
|
+
const resolvedTxSettings = {
|
|
91
|
+
criticalThreshold: settings.textureMemory?.criticalThreshold || 124e6,
|
|
92
|
+
targetThresholdLevel: settings.textureMemory?.targetThresholdLevel || 0.5,
|
|
93
|
+
cleanupInterval: settings.textureMemory?.cleanupInterval || 30000,
|
|
94
|
+
debugLogging: settings.textureMemory?.debugLogging || false,
|
|
95
|
+
};
|
|
96
|
+
const resolvedSettings = {
|
|
97
|
+
appWidth: settings.appWidth || 1920,
|
|
98
|
+
appHeight: settings.appHeight || 1080,
|
|
99
|
+
textureMemory: resolvedTxSettings,
|
|
100
|
+
boundsMargin: settings.boundsMargin || 0,
|
|
101
|
+
deviceLogicalPixelRatio: settings.deviceLogicalPixelRatio || 1,
|
|
102
|
+
devicePhysicalPixelRatio: settings.devicePhysicalPixelRatio || window.devicePixelRatio,
|
|
103
|
+
clearColor: settings.clearColor ?? 0x00000000,
|
|
104
|
+
fpsUpdateInterval: settings.fpsUpdateInterval || 0,
|
|
105
|
+
numImageWorkers: settings.numImageWorkers !== undefined ? settings.numImageWorkers : 2,
|
|
106
|
+
enableContextSpy: settings.enableContextSpy ?? false,
|
|
107
|
+
enableInspector: settings.enableInspector ?? false,
|
|
108
|
+
renderMode: settings.renderMode ?? 'webgl',
|
|
109
|
+
};
|
|
110
|
+
this.settings = resolvedSettings;
|
|
111
|
+
const { appWidth, appHeight, deviceLogicalPixelRatio, devicePhysicalPixelRatio, enableInspector, } = resolvedSettings;
|
|
112
|
+
const deviceLogicalWidth = appWidth * deviceLogicalPixelRatio;
|
|
113
|
+
const deviceLogicalHeight = appHeight * deviceLogicalPixelRatio;
|
|
114
|
+
const canvas = document.createElement('canvas');
|
|
115
|
+
this.canvas = canvas;
|
|
116
|
+
canvas.width = deviceLogicalWidth * devicePhysicalPixelRatio;
|
|
117
|
+
canvas.height = deviceLogicalHeight * devicePhysicalPixelRatio;
|
|
118
|
+
canvas.style.width = `${deviceLogicalWidth}px`;
|
|
119
|
+
canvas.style.height = `${deviceLogicalHeight}px`;
|
|
120
|
+
// Initialize the stage
|
|
121
|
+
this.stage = new Stage({
|
|
122
|
+
appWidth: this.settings.appWidth,
|
|
123
|
+
appHeight: this.settings.appHeight,
|
|
124
|
+
boundsMargin: this.settings.boundsMargin,
|
|
125
|
+
clearColor: this.settings.clearColor,
|
|
126
|
+
canvas: this.canvas,
|
|
127
|
+
deviceLogicalPixelRatio: this.settings.deviceLogicalPixelRatio,
|
|
128
|
+
devicePhysicalPixelRatio: this.settings.devicePhysicalPixelRatio,
|
|
129
|
+
enableContextSpy: this.settings.enableContextSpy,
|
|
130
|
+
fpsUpdateInterval: this.settings.fpsUpdateInterval,
|
|
131
|
+
numImageWorkers: this.settings.numImageWorkers,
|
|
132
|
+
renderMode: this.settings.renderMode,
|
|
133
|
+
textureMemory: resolvedTxSettings,
|
|
134
|
+
eventBus: this,
|
|
135
|
+
});
|
|
136
|
+
// Extract the root node
|
|
137
|
+
this.root = this.stage.root;
|
|
138
|
+
// Get the target element and attach the canvas to it
|
|
139
|
+
let targetEl;
|
|
140
|
+
if (typeof target === 'string') {
|
|
141
|
+
targetEl = document.getElementById(target);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
targetEl = target;
|
|
145
|
+
}
|
|
146
|
+
if (!targetEl) {
|
|
147
|
+
throw new Error('Could not find target element');
|
|
148
|
+
}
|
|
149
|
+
targetEl.appendChild(canvas);
|
|
150
|
+
// Initialize inspector (if enabled)
|
|
151
|
+
if (enableInspector && !isProductionEnvironment()) {
|
|
152
|
+
this.inspector = new Inspector(canvas, resolvedSettings);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Create a new scene graph node
|
|
157
|
+
*
|
|
158
|
+
* @remarks
|
|
159
|
+
* A node is the main graphical building block of the Renderer scene graph. It
|
|
160
|
+
* can be a container for other nodes, or it can be a leaf node that renders a
|
|
161
|
+
* solid color, gradient, image, or specific texture, using a specific shader.
|
|
162
|
+
*
|
|
163
|
+
* To create a text node, see {@link createTextNode}.
|
|
164
|
+
*
|
|
165
|
+
* See {@link CoreNode} for more details.
|
|
166
|
+
*
|
|
167
|
+
* @param props
|
|
168
|
+
* @returns
|
|
169
|
+
*/
|
|
170
|
+
createNode(props) {
|
|
171
|
+
assertTruthy(this.stage, 'Stage is not initialized');
|
|
172
|
+
const resolvedProps = this.resolveNodeDefaults(props);
|
|
173
|
+
const node = new CoreNode(this.stage, {
|
|
174
|
+
...resolvedProps,
|
|
175
|
+
shaderProps: null,
|
|
176
|
+
});
|
|
177
|
+
if (this.inspector) {
|
|
178
|
+
return this.inspector.createNode(node, resolvedProps);
|
|
179
|
+
}
|
|
180
|
+
// FIXME onDestroy event? node.once('beforeDestroy'
|
|
181
|
+
// FIXME onCreate event?
|
|
182
|
+
return node;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Create a new scene graph text node
|
|
186
|
+
*
|
|
187
|
+
* @remarks
|
|
188
|
+
* A text node is the second graphical building block of the Renderer scene
|
|
189
|
+
* graph. It renders text using a specific text renderer that is automatically
|
|
190
|
+
* chosen based on the font requested and what type of fonts are installed
|
|
191
|
+
* into an app.
|
|
192
|
+
*
|
|
193
|
+
* See {@link ITextNode} for more details.
|
|
194
|
+
*
|
|
195
|
+
* @param props
|
|
196
|
+
* @returns
|
|
197
|
+
*/
|
|
198
|
+
createTextNode(props) {
|
|
199
|
+
const fontSize = props.fontSize ?? 16;
|
|
200
|
+
const data = {
|
|
201
|
+
...this.resolveNodeDefaults(props),
|
|
202
|
+
id: getNewId(),
|
|
203
|
+
text: props.text ?? '',
|
|
204
|
+
textRendererOverride: props.textRendererOverride ?? null,
|
|
205
|
+
fontSize,
|
|
206
|
+
fontFamily: props.fontFamily ?? 'sans-serif',
|
|
207
|
+
fontStyle: props.fontStyle ?? 'normal',
|
|
208
|
+
fontWeight: props.fontWeight ?? 'normal',
|
|
209
|
+
fontStretch: props.fontStretch ?? 'normal',
|
|
210
|
+
textAlign: props.textAlign ?? 'left',
|
|
211
|
+
contain: props.contain ?? 'none',
|
|
212
|
+
scrollable: props.scrollable ?? false,
|
|
213
|
+
scrollY: props.scrollY ?? 0,
|
|
214
|
+
offsetY: props.offsetY ?? 0,
|
|
215
|
+
letterSpacing: props.letterSpacing ?? 0,
|
|
216
|
+
lineHeight: props.lineHeight,
|
|
217
|
+
maxLines: props.maxLines ?? 0,
|
|
218
|
+
textBaseline: props.textBaseline ?? 'alphabetic',
|
|
219
|
+
verticalAlign: props.verticalAlign ?? 'middle',
|
|
220
|
+
overflowSuffix: props.overflowSuffix ?? '...',
|
|
221
|
+
debug: props.debug ?? {},
|
|
222
|
+
shaderProps: null,
|
|
223
|
+
};
|
|
224
|
+
assertTruthy(this.stage);
|
|
225
|
+
const textNode = new CoreTextNode(this.stage, data);
|
|
226
|
+
if (this.inspector) {
|
|
227
|
+
return this.inspector.createTextNode(textNode, data);
|
|
228
|
+
}
|
|
229
|
+
return textNode;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Resolves the default property values for a Node
|
|
233
|
+
*
|
|
234
|
+
* @remarks
|
|
235
|
+
* This method is used internally by the RendererMain to resolve the default
|
|
236
|
+
* property values for a Node. It is exposed publicly so that it can be used
|
|
237
|
+
* by Core Driver implementations.
|
|
238
|
+
*
|
|
239
|
+
* @param props
|
|
240
|
+
* @returns
|
|
241
|
+
*/
|
|
242
|
+
resolveNodeDefaults(props) {
|
|
243
|
+
const color = props.color ?? 0xffffffff;
|
|
244
|
+
const colorTl = props.colorTl ?? props.colorTop ?? props.colorLeft ?? color;
|
|
245
|
+
const colorTr = props.colorTr ?? props.colorTop ?? props.colorRight ?? color;
|
|
246
|
+
const colorBl = props.colorBl ?? props.colorBottom ?? props.colorLeft ?? color;
|
|
247
|
+
const colorBr = props.colorBr ?? props.colorBottom ?? props.colorRight ?? color;
|
|
248
|
+
const data = santizeCustomDataMap(props.data ?? {});
|
|
249
|
+
return {
|
|
250
|
+
x: props.x ?? 0,
|
|
251
|
+
y: props.y ?? 0,
|
|
252
|
+
width: props.width ?? 0,
|
|
253
|
+
height: props.height ?? 0,
|
|
254
|
+
alpha: props.alpha ?? 1,
|
|
255
|
+
autosize: props.autosize ?? false,
|
|
256
|
+
clipping: props.clipping ?? false,
|
|
257
|
+
color,
|
|
258
|
+
colorTop: props.colorTop ?? color,
|
|
259
|
+
colorBottom: props.colorBottom ?? color,
|
|
260
|
+
colorLeft: props.colorLeft ?? color,
|
|
261
|
+
colorRight: props.colorRight ?? color,
|
|
262
|
+
colorBl,
|
|
263
|
+
colorBr,
|
|
264
|
+
colorTl,
|
|
265
|
+
colorTr,
|
|
266
|
+
zIndex: props.zIndex ?? 0,
|
|
267
|
+
zIndexLocked: props.zIndexLocked ?? 0,
|
|
268
|
+
parent: props.parent ?? null,
|
|
269
|
+
texture: props.texture ?? null,
|
|
270
|
+
textureOptions: props.textureOptions ?? {},
|
|
271
|
+
shader: props.shader ?? null,
|
|
272
|
+
shaderProps: props.shaderProps ?? null,
|
|
273
|
+
// Since setting the `src` will trigger a texture load, we need to set it after
|
|
274
|
+
// we set the texture. Otherwise, problems happen.
|
|
275
|
+
src: props.src ?? '',
|
|
276
|
+
scale: props.scale ?? null,
|
|
277
|
+
scaleX: props.scaleX ?? props.scale ?? 1,
|
|
278
|
+
scaleY: props.scaleY ?? props.scale ?? 1,
|
|
279
|
+
mount: props.mount ?? 0,
|
|
280
|
+
mountX: props.mountX ?? props.mount ?? 0,
|
|
281
|
+
mountY: props.mountY ?? props.mount ?? 0,
|
|
282
|
+
pivot: props.pivot ?? 0.5,
|
|
283
|
+
pivotX: props.pivotX ?? props.pivot ?? 0.5,
|
|
284
|
+
pivotY: props.pivotY ?? props.pivot ?? 0.5,
|
|
285
|
+
rotation: props.rotation ?? 0,
|
|
286
|
+
rtt: props.rtt ?? false,
|
|
287
|
+
data: data,
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Destroy a node
|
|
292
|
+
*
|
|
293
|
+
* @remarks
|
|
294
|
+
* This method destroys a node
|
|
295
|
+
*
|
|
296
|
+
* @param node
|
|
297
|
+
* @returns
|
|
298
|
+
*/
|
|
299
|
+
destroyNode(node) {
|
|
300
|
+
if (this.inspector) {
|
|
301
|
+
this.inspector.destroyNode(node.id);
|
|
302
|
+
}
|
|
303
|
+
return node.destroy();
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Create a new texture reference
|
|
307
|
+
*
|
|
308
|
+
* @remarks
|
|
309
|
+
* This method creates a new reference to a texture. The texture is not
|
|
310
|
+
* loaded until it is used on a node.
|
|
311
|
+
*
|
|
312
|
+
* It can be assigned to a node's `texture` property, or it can be used
|
|
313
|
+
* when creating a SubTexture.
|
|
314
|
+
*
|
|
315
|
+
* @param textureType
|
|
316
|
+
* @param props
|
|
317
|
+
* @param options
|
|
318
|
+
* @returns
|
|
319
|
+
*/
|
|
320
|
+
createTexture(textureType, props) {
|
|
321
|
+
return this.stage.txManager.loadTexture(textureType, props);
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Create a new shader reference
|
|
325
|
+
*
|
|
326
|
+
* @remarks
|
|
327
|
+
* This method creates a new reference to a shader. The shader is not
|
|
328
|
+
* loaded until it is used on a Node.
|
|
329
|
+
*
|
|
330
|
+
* It can be assigned to a Node's `shader` property.
|
|
331
|
+
*
|
|
332
|
+
* @param shaderType
|
|
333
|
+
* @param props
|
|
334
|
+
* @returns
|
|
335
|
+
*/
|
|
336
|
+
createShader(shaderType, props) {
|
|
337
|
+
return {
|
|
338
|
+
descType: 'shader',
|
|
339
|
+
shType: shaderType,
|
|
340
|
+
props: props,
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Get a Node by its ID
|
|
345
|
+
*
|
|
346
|
+
* @param id
|
|
347
|
+
* @returns
|
|
348
|
+
*/
|
|
349
|
+
getNodeById(id) {
|
|
350
|
+
const root = this.stage?.root;
|
|
351
|
+
if (!root) {
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
const findNode = (node) => {
|
|
355
|
+
if (node.id === id) {
|
|
356
|
+
return node;
|
|
357
|
+
}
|
|
358
|
+
for (const child of node.children) {
|
|
359
|
+
const found = findNode(child);
|
|
360
|
+
if (found) {
|
|
361
|
+
return found;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return null;
|
|
365
|
+
};
|
|
366
|
+
return findNode(root);
|
|
367
|
+
}
|
|
368
|
+
toggleFreeze() {
|
|
369
|
+
throw new Error('Not implemented');
|
|
370
|
+
}
|
|
371
|
+
advanceFrame() {
|
|
372
|
+
throw new Error('Not implemented');
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Re-render the current frame without advancing any running animations.
|
|
376
|
+
*
|
|
377
|
+
* @remarks
|
|
378
|
+
* Any state changes will be reflected in the re-rendered frame. Useful for
|
|
379
|
+
* debugging.
|
|
380
|
+
*
|
|
381
|
+
* May not do anything if the render loop is running on a separate worker.
|
|
382
|
+
*/
|
|
383
|
+
rerender() {
|
|
384
|
+
throw new Error('Not implemented');
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
//# sourceMappingURL=Renderer.js.map
|