@codexo/exojs 0.10.0 → 0.11.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/CHANGELOG.md +83 -0
- package/dist/esm/core/dev.d.ts +21 -0
- package/dist/esm/core/dev.js +18 -0
- package/dist/esm/core/dev.js.map +1 -0
- package/dist/esm/particles/modules/AlphaFadeOverLifetime.d.ts +2 -2
- package/dist/esm/particles/modules/AlphaFadeOverLifetime.js +5 -1
- package/dist/esm/particles/modules/AlphaFadeOverLifetime.js.map +1 -1
- package/dist/esm/rendering/TransformBuffer.d.ts +44 -0
- package/dist/esm/rendering/TransformBuffer.js +64 -0
- package/dist/esm/rendering/TransformBuffer.js.map +1 -1
- package/dist/esm/rendering/gradient/Gradient.d.ts +35 -2
- package/dist/esm/rendering/gradient/Gradient.js +51 -5
- package/dist/esm/rendering/gradient/Gradient.js.map +1 -1
- package/dist/esm/rendering/gradient/LinearGradient.d.ts +11 -3
- package/dist/esm/rendering/gradient/LinearGradient.js +23 -0
- package/dist/esm/rendering/gradient/LinearGradient.js.map +1 -1
- package/dist/esm/rendering/gradient/RadialGradient.d.ts +11 -3
- package/dist/esm/rendering/gradient/RadialGradient.js +19 -0
- package/dist/esm/rendering/gradient/RadialGradient.js.map +1 -1
- package/dist/esm/rendering/index.d.ts +1 -1
- package/dist/esm/rendering/pass/RenderPassCoordinator.d.ts +2 -2
- package/dist/esm/rendering/pass/RenderPassDescriptor.d.ts +2 -2
- package/dist/esm/rendering/pass/RenderPassDescriptor.js +1 -1
- package/dist/esm/rendering/plan/RenderCommand.d.ts +21 -2
- package/dist/esm/rendering/plan/RenderCommand.js +34 -1
- package/dist/esm/rendering/plan/RenderCommand.js.map +1 -1
- package/dist/esm/rendering/plan/RenderInstruction.d.ts +51 -0
- package/dist/esm/rendering/plan/RenderInstruction.js +45 -0
- package/dist/esm/rendering/plan/RenderInstruction.js.map +1 -0
- package/dist/esm/rendering/plan/RenderPlanPlayer.d.ts +4 -0
- package/dist/esm/rendering/plan/RenderPlanPlayer.js +58 -7
- package/dist/esm/rendering/plan/RenderPlanPlayer.js.map +1 -1
- package/dist/esm/rendering/primitives/Graphics.d.ts +70 -5
- package/dist/esm/rendering/primitives/Graphics.js +172 -14
- package/dist/esm/rendering/primitives/Graphics.js.map +1 -1
- package/dist/esm/rendering/sprite/spriteMaterialSources.d.ts +13 -8
- package/dist/esm/rendering/sprite/spriteMaterialSources.js +35 -14
- package/dist/esm/rendering/sprite/spriteMaterialSources.js.map +1 -1
- package/dist/esm/rendering/text/BitmapText.d.ts +2 -0
- package/dist/esm/rendering/text/BitmapText.js +8 -1
- package/dist/esm/rendering/text/BitmapText.js.map +1 -1
- package/dist/esm/rendering/text/BmFont.js +3 -0
- package/dist/esm/rendering/text/BmFont.js.map +1 -1
- package/dist/esm/rendering/text/GlyphSdf.d.ts +14 -0
- package/dist/esm/rendering/text/GlyphSdf.js +41 -11
- package/dist/esm/rendering/text/GlyphSdf.js.map +1 -1
- package/dist/esm/rendering/text/TextStyle.d.ts +5 -0
- package/dist/esm/rendering/text/TextStyle.js +1 -1
- package/dist/esm/rendering/text/TextStyle.js.map +1 -1
- package/dist/esm/rendering/texture/RenderTexture.js.map +1 -1
- package/dist/esm/rendering/webgl2/WebGl2Backend.d.ts +23 -1
- package/dist/esm/rendering/webgl2/WebGl2Backend.js +50 -0
- package/dist/esm/rendering/webgl2/WebGl2Backend.js.map +1 -1
- package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.js +3 -3
- package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.js.map +1 -1
- package/dist/esm/rendering/webgl2/WebGl2ParticleRenderer.d.ts +8 -0
- package/dist/esm/rendering/webgl2/WebGl2ParticleRenderer.js +8 -0
- package/dist/esm/rendering/webgl2/WebGl2ParticleRenderer.js.map +1 -1
- package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.d.ts +2 -0
- package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.js +62 -39
- package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.js.map +1 -1
- package/dist/esm/rendering/webgl2/WebGl2TextRenderer.d.ts +7 -0
- package/dist/esm/rendering/webgl2/WebGl2TextRenderer.js +7 -0
- package/dist/esm/rendering/webgl2/WebGl2TextRenderer.js.map +1 -1
- package/dist/esm/rendering/webgl2/glsl/sprite.vert.js +1 -1
- package/dist/esm/rendering/webgl2/glsl/text-color.frag.js +1 -1
- package/dist/esm/rendering/webgpu/WebGpuBackend.d.ts +16 -3
- package/dist/esm/rendering/webgpu/WebGpuBackend.js +49 -4
- package/dist/esm/rendering/webgpu/WebGpuBackend.js.map +1 -1
- package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.js +53 -41
- package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.js.map +1 -1
- package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.d.ts +7 -0
- package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.js +17 -11
- package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.js.map +1 -1
- package/dist/esm/rendering/webgpu/WebGpuPassCoordinator.d.ts +2 -2
- package/dist/esm/rendering/webgpu/WebGpuPassCoordinator.js +2 -2
- package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.d.ts +9 -1
- package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js +122 -77
- package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js.map +1 -1
- package/dist/esm/rendering/webgpu/WebGpuTextRenderer.d.ts +7 -0
- package/dist/esm/rendering/webgpu/WebGpuTextRenderer.js +22 -13
- package/dist/esm/rendering/webgpu/WebGpuTextRenderer.js.map +1 -1
- package/dist/esm/rendering/webgpu/WebGpuTransformStorage.d.ts +32 -0
- package/dist/esm/rendering/webgpu/WebGpuTransformStorage.js +58 -12
- package/dist/esm/rendering/webgpu/WebGpuTransformStorage.js.map +1 -1
- package/dist/esm/resources/Loader.js +1 -1
- package/dist/esm/resources/Loader.js.map +1 -1
- package/dist/exo.esm.js +1022 -265
- package/dist/exo.esm.js.map +1 -1
- package/package.json +9 -5
|
@@ -4,6 +4,7 @@ import { Gradient } from './Gradient.js';
|
|
|
4
4
|
* Radial gradient in UV space around `center` with normalized radius.
|
|
5
5
|
*/
|
|
6
6
|
class RadialGradient extends Gradient {
|
|
7
|
+
type = 'radial';
|
|
7
8
|
_center;
|
|
8
9
|
_radius;
|
|
9
10
|
constructor(stops, center = [0.5, 0.5], radius = 0.5) {
|
|
@@ -11,6 +12,17 @@ class RadialGradient extends Gradient {
|
|
|
11
12
|
this._center = [center[0], center[1]];
|
|
12
13
|
this._radius = Math.max(0, radius);
|
|
13
14
|
}
|
|
15
|
+
/** Gradient center in UV space. */
|
|
16
|
+
get center() {
|
|
17
|
+
return [this._center[0], this._center[1]];
|
|
18
|
+
}
|
|
19
|
+
/** Normalized radius (UV units, clamped to be non-negative). */
|
|
20
|
+
get radius() {
|
|
21
|
+
return this._radius;
|
|
22
|
+
}
|
|
23
|
+
clone() {
|
|
24
|
+
return new RadialGradient(this.stops, this._center, this._radius);
|
|
25
|
+
}
|
|
14
26
|
resolveT(u, v) {
|
|
15
27
|
if (this._radius <= 0.000001) {
|
|
16
28
|
return 1;
|
|
@@ -19,6 +31,13 @@ class RadialGradient extends Gradient {
|
|
|
19
31
|
const dy = v - this._center[1];
|
|
20
32
|
return Math.sqrt(dx * dx + dy * dy) / this._radius;
|
|
21
33
|
}
|
|
34
|
+
_copyGeometry(source) {
|
|
35
|
+
this._center = [source._center[0], source._center[1]];
|
|
36
|
+
this._radius = source._radius;
|
|
37
|
+
}
|
|
38
|
+
_geometryEquals(other) {
|
|
39
|
+
return other instanceof RadialGradient && this._center[0] === other._center[0] && this._center[1] === other._center[1] && this._radius === other._radius;
|
|
40
|
+
}
|
|
22
41
|
}
|
|
23
42
|
|
|
24
43
|
export { RadialGradient };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RadialGradient.js","sources":["../../../../../src/rendering/gradient/RadialGradient.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA;;AAEG;AACG,MAAO,cAAe,SAAQ,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"RadialGradient.js","sources":["../../../../../src/rendering/gradient/RadialGradient.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA;;AAEG;AACG,MAAO,cAAe,SAAQ,QAAQ,CAAA;IAC1B,IAAI,GAAiB,QAAQ;AAErC,IAAA,OAAO;AACP,IAAA,OAAO;IAEf,WAAA,CAAmB,KAA8B,EAAE,MAAA,GAAoC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,GAAG,EAAA;QAC7G,KAAK,CAAC,KAAK,CAAC;AAEZ,QAAA,IAAI,CAAC,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC;IACpC;;AAGA,IAAA,IAAW,MAAM,GAAA;AACf,QAAA,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC3C;;AAGA,IAAA,IAAW,MAAM,GAAA;QACf,OAAO,IAAI,CAAC,OAAO;IACrB;IAEO,KAAK,GAAA;AACV,QAAA,OAAO,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAS;IAC3E;IAEmB,QAAQ,CAAC,CAAS,EAAE,CAAS,EAAA;AAC9C,QAAA,IAAI,IAAI,CAAC,OAAO,IAAI,QAAQ,EAAE;AAC5B,YAAA,OAAO,CAAC;QACV;QAEA,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9B,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;AAE9B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO;IACpD;AAEmB,IAAA,aAAa,CAAC,MAAsB,EAAA;AACrD,QAAA,IAAI,CAAC,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACrD,QAAA,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO;IAC/B;AAEmB,IAAA,eAAe,CAAC,KAAe,EAAA;AAChD,QAAA,OAAO,KAAK,YAAY,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO;IAC1J;AACD;;;;"}
|
|
@@ -15,7 +15,7 @@ export type { WebGpuShaderFilterOptions } from './filters/WebGpuShaderFilter';
|
|
|
15
15
|
export { WebGpuShaderFilter } from './filters/WebGpuShaderFilter';
|
|
16
16
|
export { Geometry } from './geometry/Geometry';
|
|
17
17
|
export type { AttributeType, GeometryAttribute, GeometryOptions, GeometryUsage, Topology } from './geometry/GeometryAttribute';
|
|
18
|
-
export type { GradientStop, GradientToTextureOptions } from './gradient/Gradient';
|
|
18
|
+
export type { GradientStop, GradientToTextureOptions, GradientType } from './gradient/Gradient';
|
|
19
19
|
export { Gradient } from './gradient/Gradient';
|
|
20
20
|
export { LinearGradient } from './gradient/LinearGradient';
|
|
21
21
|
export { RadialGradient } from './gradient/RadialGradient';
|
|
@@ -6,8 +6,8 @@ import type { View } from '../View';
|
|
|
6
6
|
import type { RenderPassDescriptor, RenderPassLoad } from './RenderPassDescriptor';
|
|
7
7
|
/**
|
|
8
8
|
* Internal, backend-owned owner of render-pass lifecycle: target / view / clear
|
|
9
|
-
* orchestration, the scissor and stencil-clip stacks, and — on WebGPU
|
|
10
|
-
*
|
|
9
|
+
* orchestration, the scissor and stencil-clip stacks, and — on WebGPU — the
|
|
10
|
+
* active `GPURenderPassEncoder`.
|
|
11
11
|
*
|
|
12
12
|
* There is no public RenderPass API. This abstraction exists so the WebGL2 and
|
|
13
13
|
* WebGPU backends can share the orchestration shape that geometric stencil
|
|
@@ -5,7 +5,7 @@ import type { View } from '../View';
|
|
|
5
5
|
* Whether a render pass carries a stencil attachment.
|
|
6
6
|
*
|
|
7
7
|
* WebGL2 stencil is ambient per-target GL state, so this flag is largely
|
|
8
|
-
* informational there; the WebGPU backend
|
|
8
|
+
* informational there; the WebGPU backend uses it to
|
|
9
9
|
* decide whether a pass descriptor needs a `depthStencilAttachment`.
|
|
10
10
|
* @internal
|
|
11
11
|
*/
|
|
@@ -21,7 +21,7 @@ export type RenderPassLoad = 'clear' | 'load';
|
|
|
21
21
|
* it carries a stencil attachment.
|
|
22
22
|
*
|
|
23
23
|
* WebGL2 maps this onto ambient framebuffer / viewport / scissor / stencil
|
|
24
|
-
* state; WebGPU
|
|
24
|
+
* state; WebGPU maps it onto a `GPURenderPassEncoder`.
|
|
25
25
|
* @internal
|
|
26
26
|
*/
|
|
27
27
|
export interface RenderPassDescriptor {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Whether a render pass carries a stencil attachment.
|
|
3
3
|
*
|
|
4
4
|
* WebGL2 stencil is ambient per-target GL state, so this flag is largely
|
|
5
|
-
* informational there; the WebGPU backend
|
|
5
|
+
* informational there; the WebGPU backend uses it to
|
|
6
6
|
* decide whether a pass descriptor needs a `depthStencilAttachment`.
|
|
7
7
|
* @internal
|
|
8
8
|
*/
|
|
@@ -21,8 +21,8 @@ export declare const enum RenderEntryKind {
|
|
|
21
21
|
* group / texture-slot state.
|
|
22
22
|
*
|
|
23
23
|
* When the drawable carries a {@link Material}, both keys are taken
|
|
24
|
-
* directly from `material.pipelineKey` and `material.bindKey` (
|
|
25
|
-
*
|
|
24
|
+
* directly from `material.pipelineKey` and `material.bindKey` (the Material
|
|
25
|
+
* system). When the drawable uses its default path (no material),
|
|
26
26
|
* the keys are derived conservatively from renderer identity, blend mode,
|
|
27
27
|
* and texture identity so grouping never accidentally merges draws with
|
|
28
28
|
* incompatible state.
|
|
@@ -65,3 +65,22 @@ export interface DrawCommand {
|
|
|
65
65
|
* @internal
|
|
66
66
|
*/
|
|
67
67
|
export declare const makeMaterialKey: (drawable: Drawable, backend: RenderBackend | null) => MaterialKey;
|
|
68
|
+
/**
|
|
69
|
+
* Whether a draw command's renderer reads the shared {@link TransformBuffer} /
|
|
70
|
+
* transform storage. The render-group upload boundary packs each command's
|
|
71
|
+
* world transform (+ tint) keyed by its `nodeIndex`; only renderers that fetch
|
|
72
|
+
* those rows back from the buffer need a record written.
|
|
73
|
+
*
|
|
74
|
+
* Sprite and Mesh (and their subclasses — {@link AnimatedSprite}, Video,
|
|
75
|
+
* Graphics' meshes) fetch the transform via `nodeIndex` and therefore consume
|
|
76
|
+
* it. Text/BitmapText and particle renderers pack their own per-node data into
|
|
77
|
+
* a private data texture / uniforms and never touch the shared buffer, so they
|
|
78
|
+
* opt out via `_consumesSharedTransform === false` and their writes are skipped.
|
|
79
|
+
*
|
|
80
|
+
* Anything else — a custom renderer, or a drawable with no registered renderer
|
|
81
|
+
* (resolve throws) — defaults to writing, so behaviour is unchanged for any
|
|
82
|
+
* path that might still rely on the shared transform.
|
|
83
|
+
*
|
|
84
|
+
* @internal
|
|
85
|
+
*/
|
|
86
|
+
export declare const drawCommandUsesSharedTransform: (command: DrawCommand, backend: RenderBackend) => boolean;
|
|
@@ -89,6 +89,39 @@ const makeMaterialKey = (drawable, backend) => {
|
|
|
89
89
|
bindKey,
|
|
90
90
|
};
|
|
91
91
|
};
|
|
92
|
+
/**
|
|
93
|
+
* Whether a draw command's renderer reads the shared {@link TransformBuffer} /
|
|
94
|
+
* transform storage. The render-group upload boundary packs each command's
|
|
95
|
+
* world transform (+ tint) keyed by its `nodeIndex`; only renderers that fetch
|
|
96
|
+
* those rows back from the buffer need a record written.
|
|
97
|
+
*
|
|
98
|
+
* Sprite and Mesh (and their subclasses — {@link AnimatedSprite}, Video,
|
|
99
|
+
* Graphics' meshes) fetch the transform via `nodeIndex` and therefore consume
|
|
100
|
+
* it. Text/BitmapText and particle renderers pack their own per-node data into
|
|
101
|
+
* a private data texture / uniforms and never touch the shared buffer, so they
|
|
102
|
+
* opt out via `_consumesSharedTransform === false` and their writes are skipped.
|
|
103
|
+
*
|
|
104
|
+
* Anything else — a custom renderer, or a drawable with no registered renderer
|
|
105
|
+
* (resolve throws) — defaults to writing, so behaviour is unchanged for any
|
|
106
|
+
* path that might still rely on the shared transform.
|
|
107
|
+
*
|
|
108
|
+
* @internal
|
|
109
|
+
*/
|
|
110
|
+
const drawCommandUsesSharedTransform = (command, backend) => {
|
|
111
|
+
const registry = backend.rendererRegistry;
|
|
112
|
+
if (!registry || typeof registry.resolve !== 'function') {
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
try {
|
|
116
|
+
const renderer = registry.resolve(command.drawable);
|
|
117
|
+
return renderer._consumesSharedTransform !== false;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// No renderer registered for a custom drawable: keep the conservative
|
|
121
|
+
// write so any consumer of the shared transform keeps working.
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
92
125
|
|
|
93
|
-
export { RenderEntryKind, makeMaterialKey };
|
|
126
|
+
export { RenderEntryKind, drawCommandUsesSharedTransform, makeMaterialKey };
|
|
94
127
|
//# sourceMappingURL=RenderCommand.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RenderCommand.js","sources":["../../../../../src/rendering/plan/RenderCommand.ts"],"sourcesContent":[null],"names":[],"mappings":"AAOA;IACkB;AAAlB,CAAA,UAAkB,eAAe,EAAA;AAC/B,IAAA,eAAA,CAAA,eAAA,CAAA,MAAA,CAAA,GAAA,CAAA,CAAA,GAAA,MAAI;AACJ,IAAA,eAAA,CAAA,eAAA,CAAA,OAAA,CAAA,GAAA,CAAA,CAAA,GAAA,OAAK;AACL,IAAA,eAAA,CAAA,eAAA,CAAA,SAAA,CAAA,GAAA,CAAA,CAAA,GAAA,SAAO;AACT,CAAC,EAJiB,eAAe,KAAf,eAAe,GAAA,EAAA,CAAA,CAAA;
|
|
1
|
+
{"version":3,"file":"RenderCommand.js","sources":["../../../../../src/rendering/plan/RenderCommand.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { type DrawCommand, type MaterialKey } from './RenderCommand';
|
|
2
|
+
import type { GroupScope } from './RenderScope';
|
|
3
|
+
/**
|
|
4
|
+
* The canonical, reorderable unit of work in a render plan: a single draw
|
|
5
|
+
* that the plan player submits to the backend.
|
|
6
|
+
*
|
|
7
|
+
* Today a render instruction is exactly a {@link DrawCommand}; the alias
|
|
8
|
+
* names the concept the plan player consumes and that the batching layer
|
|
9
|
+
* reorders, independent of how the draw happens to be stored in the scope
|
|
10
|
+
* tree. Future {@link TransformBuffer} slotting keys on each instruction's
|
|
11
|
+
* stable {@link DrawCommand.nodeIndex} (within the `[0, plan.nodeCount)`
|
|
12
|
+
* slot space).
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export type RenderInstruction = DrawCommand;
|
|
17
|
+
/**
|
|
18
|
+
* A materialized batch unit: a maximal run of consecutive
|
|
19
|
+
* {@link RenderInstruction}s within a single {@link GroupScope} that share a
|
|
20
|
+
* GPU pipeline/bind state and may therefore be submitted together.
|
|
21
|
+
*
|
|
22
|
+
* The optimizer ({@link RenderPlanOptimizer}) already stamps this grouping
|
|
23
|
+
* implicitly onto each {@link DrawCommand.groupIndex}; a `RenderGroup` makes
|
|
24
|
+
* that batch unit explicit as a value without altering playback. The mesh
|
|
25
|
+
* renderers continue to detect batches by comparing adjacent `groupIndex`es,
|
|
26
|
+
* so this representation is purely additive.
|
|
27
|
+
*
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
export interface RenderGroup {
|
|
31
|
+
/** Optimizer-assigned batch identity shared by every instruction in the run. */
|
|
32
|
+
readonly groupIndex: number;
|
|
33
|
+
/** Pipeline/bind state shared by the run; taken from its first instruction. */
|
|
34
|
+
readonly material: MaterialKey;
|
|
35
|
+
/** Draw instructions in submit order. */
|
|
36
|
+
readonly instructions: readonly RenderInstruction[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Materialize the {@link RenderGroup} batch units contained directly in
|
|
40
|
+
* `scope`. Consecutive draw instructions that share a defined `groupIndex`
|
|
41
|
+
* coalesce into one group; any non-draw entry (a nested group or barrier)
|
|
42
|
+
* breaks the run, and a draw whose `groupIndex` is still `undefined` (i.e.
|
|
43
|
+
* the plan has not been optimized) forms its own singleton group — mirroring
|
|
44
|
+
* the adjacency semantics the mesh renderers already rely on.
|
|
45
|
+
*
|
|
46
|
+
* This is a read-only view over an (optimized) scope; it does not mutate the
|
|
47
|
+
* plan or affect playback order.
|
|
48
|
+
*
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
export declare function collectRenderGroups(scope: GroupScope): RenderGroup[];
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { RenderEntryKind } from './RenderCommand.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Materialize the {@link RenderGroup} batch units contained directly in
|
|
5
|
+
* `scope`. Consecutive draw instructions that share a defined `groupIndex`
|
|
6
|
+
* coalesce into one group; any non-draw entry (a nested group or barrier)
|
|
7
|
+
* breaks the run, and a draw whose `groupIndex` is still `undefined` (i.e.
|
|
8
|
+
* the plan has not been optimized) forms its own singleton group — mirroring
|
|
9
|
+
* the adjacency semantics the mesh renderers already rely on.
|
|
10
|
+
*
|
|
11
|
+
* This is a read-only view over an (optimized) scope; it does not mutate the
|
|
12
|
+
* plan or affect playback order.
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
function collectRenderGroups(scope) {
|
|
17
|
+
const groups = [];
|
|
18
|
+
let current = null;
|
|
19
|
+
for (const entry of scope.entries) {
|
|
20
|
+
if (entry.kind !== RenderEntryKind.Draw) {
|
|
21
|
+
current = null;
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
const command = entry.command;
|
|
25
|
+
const groupIndex = command.groupIndex;
|
|
26
|
+
if (current !== null && groupIndex !== undefined && groupIndex === current.groupIndex) {
|
|
27
|
+
current.instructions.push(command);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
current = {
|
|
31
|
+
groupIndex: groupIndex ?? 0,
|
|
32
|
+
material: command.material,
|
|
33
|
+
instructions: [command],
|
|
34
|
+
};
|
|
35
|
+
groups.push(current);
|
|
36
|
+
if (groupIndex === undefined) {
|
|
37
|
+
// Unoptimized / non-batchable draw: never coalesce with the next one.
|
|
38
|
+
current = null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return groups;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { collectRenderGroups };
|
|
45
|
+
//# sourceMappingURL=RenderInstruction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RenderInstruction.js","sources":["../../../../../src/rendering/plan/RenderInstruction.ts"],"sourcesContent":[null],"names":[],"mappings":";;AA8CA;;;;;;;;;;;;AAYG;AACG,SAAU,mBAAmB,CAAC,KAAiB,EAAA;IACnD,MAAM,MAAM,GAAkB,EAAE;IAChC,IAAI,OAAO,GAA8B,IAAI;AAE7C,IAAA,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE;QACjC,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,CAAC,IAAI,EAAE;YACvC,OAAO,GAAG,IAAI;YAEd;QACF;AAEA,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO;AAC7B,QAAA,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU;AAErC,QAAA,IAAI,OAAO,KAAK,IAAI,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,OAAO,CAAC,UAAU,EAAE;AACrF,YAAA,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC;YAElC;QACF;AAEA,QAAA,OAAO,GAAG;YACR,UAAU,EAAE,UAAU,IAAI,CAAC;YAC3B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,YAAY,EAAE,CAAC,OAAO,CAAC;SACxB;AACD,QAAA,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;AAEpB,QAAA,IAAI,UAAU,KAAK,SAAS,EAAE;;YAE5B,OAAO,GAAG,IAAI;QAChB;IACF;AAEA,IAAA,OAAO,MAAM;AACf;;;;"}
|
|
@@ -5,5 +5,9 @@ import type { RenderScope } from './RenderScope';
|
|
|
5
5
|
export declare class RenderPlanPlayer {
|
|
6
6
|
static play(plan: RenderPlan, backend: RenderBackend): void;
|
|
7
7
|
static playScope(scope: RenderScope, backend: RenderBackend): void;
|
|
8
|
+
private static _playScope;
|
|
8
9
|
private static _playGroup;
|
|
10
|
+
private static _createPlaybackContext;
|
|
11
|
+
private static _createRenderGroupPlaybackContext;
|
|
12
|
+
private static _createRenderInstructionSlot;
|
|
9
13
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RenderEntryKind } from './RenderCommand.js';
|
|
2
2
|
import { RenderEffectExecutor } from './RenderEffectExecutor.js';
|
|
3
|
+
import { collectRenderGroups } from './RenderInstruction.js';
|
|
3
4
|
|
|
4
5
|
/** @internal */
|
|
5
6
|
class RenderPlanPlayer {
|
|
@@ -17,7 +18,7 @@ class RenderPlanPlayer {
|
|
|
17
18
|
if (pass.clearColor !== null) {
|
|
18
19
|
backend.clear(pass.clearColor);
|
|
19
20
|
}
|
|
20
|
-
this.
|
|
21
|
+
this._playScope(pass.root, backend, hooks, this._createPlaybackContext());
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
finally {
|
|
@@ -25,31 +26,81 @@ class RenderPlanPlayer {
|
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
static playScope(scope, backend) {
|
|
29
|
+
const hooks = backend;
|
|
30
|
+
this._playScope(scope, backend, hooks, this._createPlaybackContext());
|
|
31
|
+
}
|
|
32
|
+
static _playScope(scope, backend, hooks, context) {
|
|
28
33
|
if (scope.kind === RenderEntryKind.Barrier) {
|
|
29
34
|
RenderEffectExecutor.play(scope, backend, childScope => {
|
|
30
|
-
this.
|
|
35
|
+
this._playScope(childScope, backend, hooks, context);
|
|
31
36
|
});
|
|
32
37
|
return;
|
|
33
38
|
}
|
|
34
|
-
this._playGroup(scope, backend);
|
|
39
|
+
this._playGroup(scope, backend, hooks, context);
|
|
35
40
|
}
|
|
36
|
-
static _playGroup(scope, backend) {
|
|
37
|
-
const
|
|
41
|
+
static _playGroup(scope, backend, hooks, context) {
|
|
42
|
+
const groups = collectRenderGroups(scope);
|
|
43
|
+
let groupCursor = 0;
|
|
44
|
+
let currentGroup = null;
|
|
45
|
+
let currentInstructionIndex = 0;
|
|
38
46
|
for (const entry of scope.entries) {
|
|
39
47
|
if (entry.kind === RenderEntryKind.Draw) {
|
|
48
|
+
if (currentGroup === null) {
|
|
49
|
+
currentGroup = groups[groupCursor];
|
|
50
|
+
currentInstructionIndex = 0;
|
|
51
|
+
hooks._beginRenderGroup?.(currentGroup);
|
|
52
|
+
hooks._prepareRenderGroupUpload?.(currentGroup, this._createRenderGroupPlaybackContext(currentGroup.instructions.length, context.passInstructionIndex, context.passGroupIndex));
|
|
53
|
+
context.passGroupIndex++;
|
|
54
|
+
}
|
|
55
|
+
// Allocate the per-draw instruction slot only when a backend consumes
|
|
56
|
+
// it. No shipped backend implements `_prepareRenderInstructionSlot`, so
|
|
57
|
+
// skipping the `Object.freeze` slot allocation removes per-draw garbage
|
|
58
|
+
// from the playback hot path while preserving the extension point.
|
|
59
|
+
if (hooks._prepareRenderInstructionSlot !== undefined) {
|
|
60
|
+
const slot = this._createRenderInstructionSlot(currentInstructionIndex, context.passInstructionIndex);
|
|
61
|
+
hooks._prepareRenderInstructionSlot(entry.command, slot);
|
|
62
|
+
}
|
|
40
63
|
hooks._prepareDrawCommand?.(entry.command);
|
|
41
64
|
backend.draw(entry.command.drawable);
|
|
65
|
+
currentInstructionIndex++;
|
|
66
|
+
context.passInstructionIndex++;
|
|
67
|
+
if (currentGroup !== null && currentInstructionIndex === currentGroup.instructions.length) {
|
|
68
|
+
hooks._endRenderGroup?.(currentGroup);
|
|
69
|
+
currentGroup = null;
|
|
70
|
+
currentInstructionIndex = 0;
|
|
71
|
+
groupCursor++;
|
|
72
|
+
}
|
|
42
73
|
}
|
|
43
74
|
else if (entry.kind === RenderEntryKind.Group) {
|
|
44
|
-
this._playGroup(entry.scope, backend);
|
|
75
|
+
this._playGroup(entry.scope, backend, hooks, context);
|
|
45
76
|
}
|
|
46
77
|
else {
|
|
47
78
|
RenderEffectExecutor.play(entry.scope, backend, childScope => {
|
|
48
|
-
this.
|
|
79
|
+
this._playScope(childScope, backend, hooks, context);
|
|
49
80
|
});
|
|
50
81
|
}
|
|
51
82
|
}
|
|
52
83
|
}
|
|
84
|
+
static _createPlaybackContext() {
|
|
85
|
+
return {
|
|
86
|
+
passInstructionIndex: 0,
|
|
87
|
+
passGroupIndex: 0,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
static _createRenderGroupPlaybackContext(groupInstructionCount, firstPassInstructionIndex, passGroupIndex) {
|
|
91
|
+
return Object.freeze({
|
|
92
|
+
groupInstructionCount,
|
|
93
|
+
firstPassInstructionIndex,
|
|
94
|
+
lastPassInstructionIndex: firstPassInstructionIndex + groupInstructionCount - 1,
|
|
95
|
+
passGroupIndex,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
static _createRenderInstructionSlot(groupInstructionIndex, passInstructionIndex) {
|
|
99
|
+
return Object.freeze({
|
|
100
|
+
groupInstructionIndex,
|
|
101
|
+
passInstructionIndex,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
53
104
|
}
|
|
54
105
|
|
|
55
106
|
export { RenderPlanPlayer };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RenderPlanPlayer.js","sources":["../../../../../src/rendering/plan/RenderPlanPlayer.ts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RenderPlanPlayer.js","sources":["../../../../../src/rendering/plan/RenderPlanPlayer.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -1,32 +1,79 @@
|
|
|
1
1
|
import { Color } from '@/core/Color';
|
|
2
2
|
import { Vector } from '@/math/Vector';
|
|
3
3
|
import { Container } from '@/rendering/Container';
|
|
4
|
+
import type { Gradient } from '@/rendering/gradient/Gradient';
|
|
4
5
|
import { Mesh } from '@/rendering/mesh/Mesh';
|
|
5
6
|
import type { RenderNode } from '@/rendering/RenderNode';
|
|
6
7
|
/**
|
|
7
8
|
* Immediate-mode 2D shape API backed by {@link Mesh} children.
|
|
8
9
|
*
|
|
9
10
|
* Each draw call (e.g. `drawCircle`, `drawRectangle`, `drawLine`) appends a
|
|
10
|
-
* new {@link Mesh} child
|
|
11
|
+
* new {@link Mesh} child painted with the active fill or stroke style. A style
|
|
12
|
+
* is either a solid {@link Color} or a {@link Gradient}, assigned through
|
|
13
|
+
* {@link fillStyle} / {@link strokeStyle}. The {@link fillColor} /
|
|
14
|
+
* {@link lineColor} accessors are color-only conveniences over those styles.
|
|
11
15
|
* The active `lineWidth` controls stroke thickness for path and outline draws.
|
|
12
16
|
* Path commands (`moveTo`, `lineTo`, `quadraticCurveTo`, etc.) track a cursor
|
|
13
17
|
* point and flush a Mesh on each segment.
|
|
14
18
|
*
|
|
19
|
+
* Gradient styles are rasterized once to a {@link DataTexture} via
|
|
20
|
+
* {@link Gradient.toTexture} and sampled across each shape's local bounding
|
|
21
|
+
* box, so {@link LinearGradient} and {@link RadialGradient} render through the
|
|
22
|
+
* same texture path as a textured Mesh. The textures are owned by the Graphics
|
|
23
|
+
* and released on {@link clear} / {@link destroy}.
|
|
24
|
+
*
|
|
15
25
|
* Call {@link clear} to remove all child meshes and reset pen state. Because
|
|
16
26
|
* each shape is a separate Mesh, `Graphics` inherits full filter, blend,
|
|
17
27
|
* tint, and mask support from {@link Container}.
|
|
18
28
|
*/
|
|
19
29
|
export declare class Graphics extends Container {
|
|
20
30
|
private _lineWidth;
|
|
21
|
-
private
|
|
22
|
-
private
|
|
31
|
+
private readonly _fillColor;
|
|
32
|
+
private readonly _lineColor;
|
|
33
|
+
private _fillStyle;
|
|
34
|
+
private _strokeStyle;
|
|
35
|
+
private _fillStyleTexture;
|
|
36
|
+
private _strokeStyleTexture;
|
|
37
|
+
private readonly _ownedTextures;
|
|
23
38
|
private _currentPoint;
|
|
24
39
|
get lineWidth(): number;
|
|
25
40
|
set lineWidth(lineWidth: number);
|
|
41
|
+
/** Solid stroke color slot: the last solid color assigned to the stroke. */
|
|
26
42
|
get lineColor(): Color;
|
|
43
|
+
/**
|
|
44
|
+
* Convenience solid-color setter for the stroke. Copies `lineColor` into the
|
|
45
|
+
* color slot and makes it the active {@link strokeStyle}, replacing any
|
|
46
|
+
* gradient stroke style.
|
|
47
|
+
*/
|
|
27
48
|
set lineColor(lineColor: Color);
|
|
49
|
+
/** Solid fill color slot: the last solid color assigned to the fill. */
|
|
28
50
|
get fillColor(): Color;
|
|
51
|
+
/**
|
|
52
|
+
* Convenience solid-color setter for the fill. Copies `fillColor` into the
|
|
53
|
+
* color slot and makes it the active {@link fillStyle}, replacing any
|
|
54
|
+
* gradient fill style.
|
|
55
|
+
*/
|
|
29
56
|
set fillColor(fillColor: Color);
|
|
57
|
+
/** Active fill style: a solid {@link Color} or a {@link Gradient}. */
|
|
58
|
+
get fillStyle(): Color | Gradient;
|
|
59
|
+
/**
|
|
60
|
+
* Set the fill style. Accepts a solid {@link Color}, a {@link Gradient}
|
|
61
|
+
* (cloned on assignment and rasterized lazily on first fill), or `null` to
|
|
62
|
+
* revert to the solid color held by {@link fillColor}. A {@link Color} value
|
|
63
|
+
* is copied into the {@link fillColor} slot; the most recently assigned style
|
|
64
|
+
* wins.
|
|
65
|
+
*/
|
|
66
|
+
set fillStyle(style: Color | Gradient | null);
|
|
67
|
+
/** Active stroke style: a solid {@link Color} or a {@link Gradient}. */
|
|
68
|
+
get strokeStyle(): Color | Gradient;
|
|
69
|
+
/**
|
|
70
|
+
* Set the stroke style. Accepts a solid {@link Color}, a {@link Gradient}
|
|
71
|
+
* (cloned on assignment and rasterized lazily on first stroke), or `null` to
|
|
72
|
+
* revert to the solid color held by {@link lineColor}. A {@link Color} value
|
|
73
|
+
* is copied into the {@link lineColor} slot; the most recently assigned style
|
|
74
|
+
* wins.
|
|
75
|
+
*/
|
|
76
|
+
set strokeStyle(style: Color | Gradient | null);
|
|
30
77
|
get currentPoint(): Vector;
|
|
31
78
|
getChildAt(index: number): Mesh;
|
|
32
79
|
addChild(child: RenderNode): this;
|
|
@@ -64,8 +111,26 @@ export declare class Graphics extends Container {
|
|
|
64
111
|
* `innerRadius` defaults to half of `radius`.
|
|
65
112
|
*/
|
|
66
113
|
drawStar(centerX: number, centerY: number, points: number, radius: number, innerRadius?: number, rotation?: number): this;
|
|
67
|
-
/** Remove all child meshes and reset pen state (position,
|
|
114
|
+
/** Remove all child meshes and reset pen state (position, fill/stroke styles, line width). */
|
|
68
115
|
clear(): this;
|
|
69
116
|
destroy(): void;
|
|
70
|
-
|
|
117
|
+
/**
|
|
118
|
+
* Resolve an assigned style into the stored paint. A {@link Color} is copied
|
|
119
|
+
* into the solid `colorSlot` (keeping the {@link fillColor} / {@link lineColor}
|
|
120
|
+
* convenience getters in sync) and that slot is returned; `null` reverts to
|
|
121
|
+
* the slot; a {@link Gradient} is cloned so later external mutation cannot
|
|
122
|
+
* change the stored paint.
|
|
123
|
+
*/
|
|
124
|
+
private _resolveStyle;
|
|
125
|
+
private _createFillMesh;
|
|
126
|
+
private _createStrokeMesh;
|
|
127
|
+
private _createSolidMesh;
|
|
128
|
+
/**
|
|
129
|
+
* Build a textured mesh whose UVs span the shape's local bounding box, so the
|
|
130
|
+
* gradient texture samples across the filled/stroked geometry. The default
|
|
131
|
+
* white tint and vertex color leave the sampled gradient color unmodulated.
|
|
132
|
+
*/
|
|
133
|
+
private _createGradientMesh;
|
|
134
|
+
private _rasterizeGradient;
|
|
135
|
+
private _destroyOwnedTextures;
|
|
71
136
|
}
|