@kurot/core 2.1.1 → 2.2.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 +41 -0
- package/README.md +37 -2
- package/dist/kurot/display/DisplayObject.d.ts +2 -1
- package/dist/kurot/display/DisplayObject.d.ts.map +1 -1
- package/dist/kurot/display/DisplayObject.js.map +1 -1
- package/dist/kurot/player/canvas/CanvasRenderer.d.ts +2 -0
- package/dist/kurot/player/canvas/CanvasRenderer.d.ts.map +1 -1
- package/dist/kurot/player/canvas/CanvasRenderer.js +37 -1
- package/dist/kurot/player/canvas/CanvasRenderer.js.map +1 -1
- package/dist/kurot/player/pipes/BitmapTextPipe.d.ts +20 -0
- package/dist/kurot/player/pipes/BitmapTextPipe.d.ts.map +1 -0
- package/dist/kurot/player/pipes/BitmapTextPipe.js +27 -0
- package/dist/kurot/player/pipes/BitmapTextPipe.js.map +1 -0
- package/dist/kurot/player/pipes/index.d.ts +2 -0
- package/dist/kurot/player/pipes/index.d.ts.map +1 -1
- package/dist/kurot/player/pipes/index.js +1 -0
- package/dist/kurot/player/pipes/index.js.map +1 -1
- package/dist/kurot/player/webgl/WebGLRenderer.d.ts +1 -0
- package/dist/kurot/player/webgl/WebGLRenderer.d.ts.map +1 -1
- package/dist/kurot/player/webgl/WebGLRenderer.js +8 -0
- package/dist/kurot/player/webgl/WebGLRenderer.js.map +1 -1
- package/dist/kurot/resource/Resource.d.ts.map +1 -1
- package/dist/kurot/resource/Resource.js +4 -0
- package/dist/kurot/resource/Resource.js.map +1 -1
- package/dist/kurot/resource/ResourceItem.d.ts +1 -0
- package/dist/kurot/resource/ResourceItem.d.ts.map +1 -1
- package/dist/kurot/resource/ResourceItem.js +1 -0
- package/dist/kurot/resource/ResourceItem.js.map +1 -1
- package/dist/kurot/resource/analyzers/FontAnalyzer.d.ts +16 -0
- package/dist/kurot/resource/analyzers/FontAnalyzer.d.ts.map +1 -0
- package/dist/kurot/resource/analyzers/FontAnalyzer.js +75 -0
- package/dist/kurot/resource/analyzers/FontAnalyzer.js.map +1 -0
- package/dist/kurot/resource/analyzers/index.d.ts +1 -0
- package/dist/kurot/resource/analyzers/index.d.ts.map +1 -1
- package/dist/kurot/resource/analyzers/index.js +1 -0
- package/dist/kurot/resource/analyzers/index.js.map +1 -1
- package/dist/kurot/resource/index.d.ts +1 -0
- package/dist/kurot/resource/index.d.ts.map +1 -1
- package/dist/kurot/resource/index.js +1 -0
- package/dist/kurot/resource/index.js.map +1 -1
- package/dist/kurot/text/BitmapFont.d.ts +15 -21
- package/dist/kurot/text/BitmapFont.d.ts.map +1 -1
- package/dist/kurot/text/BitmapFont.js +59 -66
- package/dist/kurot/text/BitmapFont.js.map +1 -1
- package/dist/kurot/text/BitmapText.d.ts +29 -19
- package/dist/kurot/text/BitmapText.d.ts.map +1 -1
- package/dist/kurot/text/BitmapText.js +93 -141
- package/dist/kurot/text/BitmapText.js.map +1 -1
- package/dist/kurot/text/index.d.ts +1 -0
- package/dist/kurot/text/index.d.ts.map +1 -1
- package/dist/kurot/text/index.js.map +1 -1
- package/docs/ai-context.md +22 -7
- package/docs/architecture.md +322 -276
- package/docs/bitmap-fonts.md +85 -0
- package/docs/resource.md +185 -156
- package/docs/text-layout.md +8 -6
- package/package.json +3 -2
package/docs/architecture.md
CHANGED
|
@@ -1,228 +1,253 @@
|
|
|
1
|
-
# @kurot/core
|
|
1
|
+
# @kurot/core architecture
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
>
|
|
3
|
+
> Package version: 2.2.0. See [CHANGELOG.md](../CHANGELOG.md) for release notes.
|
|
4
|
+
> The [AI context map](./ai-context.md) covers directories, non-obvious behavior,
|
|
5
|
+
> terminology and task-to-file references. This document explains design choices
|
|
6
|
+
> and internal mechanisms for contributors; the two documents complement each other.
|
|
5
7
|
|
|
6
8
|
---
|
|
7
9
|
|
|
8
|
-
##
|
|
10
|
+
## 1. Overview
|
|
9
11
|
|
|
10
|
-
`@kurot/core`
|
|
12
|
+
`@kurot/core` provides Kurot's display objects, rendering, events, geometry, text,
|
|
13
|
+
resources, networking and media runtime. Public APIs follow Egret's
|
|
14
|
+
`DisplayObject` and event model, while rendering uses a flat
|
|
15
|
+
`InstructionSet + RenderPipe` pipeline inspired by Pixi.js 8.
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
| 类型系统 | `strict: true`,全量类型安全,零 `any` |
|
|
16
|
-
| 编译目标 | ES2022,仅支持现代浏览器 |
|
|
17
|
-
| 渲染架构 | InstructionSet 指令驱动(借鉴 Pixi.js 8) |
|
|
18
|
-
| 批处理 | 多纹理批处理(8 张/批) |
|
|
19
|
-
| 包管理 | `@kurot/core` workspace 包,pnpm |
|
|
20
|
-
| 资源管理 | Resource 完整资源生命周期 |
|
|
21
|
-
| WebGL | WebGL 1 + WebGL 2 双后端,运行时自动选择 |
|
|
17
|
+
Version 2.2.0 uses published `@kurot/bitmap-font ^0.1.0` as the headless font-data
|
|
18
|
+
and layout kernel. Core manages font resources, image-page ownership and glyph
|
|
19
|
+
drawing in both backends. UI components belong to the UI package.
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
| Aspect | Description |
|
|
22
|
+
| ------------------ | ---------------------------------------------------------- |
|
|
23
|
+
| Modules | ES modules (`@kurot/core` npm package) |
|
|
24
|
+
| Types | Strict TypeScript (`strict: true`) |
|
|
25
|
+
| Target | ES2022 and modern browsers |
|
|
26
|
+
| Rendering | InstructionSet pipeline inspired by Pixi.js 8 |
|
|
27
|
+
| Batching | Multiple textures, up to 8 per batch |
|
|
28
|
+
| Package management | Independent pnpm package |
|
|
29
|
+
| Resources | Loading, caching and lifecycle management through Resource |
|
|
30
|
+
| WebGL | WebGL 1 and WebGL 2, selected at runtime |
|
|
31
|
+
|
|
32
|
+
See [Egret migration](../../../docs/egret-migration.md) for differences,
|
|
33
|
+
breaking changes and migration guidance.
|
|
24
34
|
|
|
25
35
|
---
|
|
26
36
|
|
|
27
|
-
##
|
|
37
|
+
## 2. Module structure
|
|
28
38
|
|
|
29
39
|
```
|
|
30
40
|
packages/core/src/kurot/
|
|
31
|
-
├── display/
|
|
32
|
-
│ ├── DisplayObject.ts
|
|
33
|
-
│ ├── DisplayObjectContainer.ts
|
|
34
|
-
│ ├── Bitmap.ts
|
|
35
|
-
│ ├── Sprite.ts
|
|
36
|
-
│ ├── Shape.ts
|
|
37
|
-
│ ├── Mesh.ts
|
|
38
|
-
│ ├── Stage.ts
|
|
39
|
-
│ ├── Graphics.ts
|
|
40
|
-
│ ├── GraphicsPath.ts
|
|
41
|
-
│ ├── enums/
|
|
42
|
-
│ └── texture/
|
|
43
|
-
├── player/
|
|
44
|
-
│ ├── Player.ts
|
|
45
|
-
│ ├── SystemTicker.ts
|
|
46
|
-
│ ├── RenderPipe.ts
|
|
47
|
-
│ ├──
|
|
48
|
-
│ ├──
|
|
49
|
-
│ ├──
|
|
50
|
-
│ ├──
|
|
51
|
-
│ ├──
|
|
52
|
-
│
|
|
53
|
-
│ │ ├──
|
|
54
|
-
│ │
|
|
55
|
-
│
|
|
56
|
-
│
|
|
57
|
-
│
|
|
58
|
-
│
|
|
59
|
-
│
|
|
60
|
-
│
|
|
61
|
-
│
|
|
62
|
-
│
|
|
63
|
-
│
|
|
64
|
-
│
|
|
65
|
-
│
|
|
66
|
-
│ ├──
|
|
67
|
-
│
|
|
68
|
-
│
|
|
69
|
-
│
|
|
70
|
-
│
|
|
71
|
-
│
|
|
72
|
-
│
|
|
73
|
-
│
|
|
74
|
-
│
|
|
75
|
-
│
|
|
76
|
-
│
|
|
77
|
-
|
|
78
|
-
├──
|
|
79
|
-
├──
|
|
80
|
-
├──
|
|
81
|
-
|
|
82
|
-
│ ├──
|
|
83
|
-
│ ├──
|
|
84
|
-
│ ├──
|
|
85
|
-
│ ├──
|
|
86
|
-
│ ├──
|
|
87
|
-
│ ├──
|
|
88
|
-
│ ├──
|
|
89
|
-
│ ├──
|
|
90
|
-
│ ├──
|
|
91
|
-
│ ├──
|
|
92
|
-
│
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
│ ├──
|
|
96
|
-
│ ├──
|
|
97
|
-
│ ├──
|
|
98
|
-
│ ├──
|
|
99
|
-
│
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
├──
|
|
104
|
-
├──
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
41
|
+
├── display/ # scene graph
|
|
42
|
+
│ ├── DisplayObject.ts # base class, dirty flags, render mode/type and cached bounds
|
|
43
|
+
│ ├── DisplayObjectContainer.ts # containers, render groups and zIndex sorting
|
|
44
|
+
│ ├── Bitmap.ts # bitmap display with scale9Grid
|
|
45
|
+
│ ├── Sprite.ts # container with Graphics
|
|
46
|
+
│ ├── Shape.ts # vector shapes
|
|
47
|
+
│ ├── Mesh.ts # vertices, indices and UVs
|
|
48
|
+
│ ├── Stage.ts # scene root
|
|
49
|
+
│ ├── Graphics.ts # vector drawing commands
|
|
50
|
+
│ ├── GraphicsPath.ts # PathCommandType and GraphicsCommand
|
|
51
|
+
│ ├── enums/ # BlendMode, BitmapFillMode, CapsStyle, GradientType, JointStyle, OrientationMode, StageScaleMode
|
|
52
|
+
│ └── texture/ # BitmapData, Texture, SpriteSheet, RenderTexture
|
|
53
|
+
├── player/ # rendering pipeline and game loop
|
|
54
|
+
│ ├── Player.ts # Stage/renderer integration and performance metrics
|
|
55
|
+
│ ├── SystemTicker.ts # RAF loop, ENTER_FRAME and callLater queue
|
|
56
|
+
│ ├── RenderPipe.ts # RenderPipe interface
|
|
57
|
+
│ ├── InstructionSet.ts # instruction list, renderableIndex and incremental dirty updates
|
|
58
|
+
│ ├── TouchHandler.ts # touch and mouse input
|
|
59
|
+
│ ├── ScreenAdapter.ts # screen adaptation with 7 scale modes
|
|
60
|
+
│ ├── createPlayer.ts # initialization and RenderTexture renderer setup
|
|
61
|
+
│ ├── KurotOptions.ts # player options
|
|
62
|
+
│ ├── pipes/ # RenderPipe implementations
|
|
63
|
+
│ │ ├── BitmapPipe.ts # bitmap instructions
|
|
64
|
+
│ │ ├── BitmapTextPipe.ts # native bitmap-font glyph instructions
|
|
65
|
+
│ │ ├── GraphicsPipe.ts # Canvas rasterization and texture upload
|
|
66
|
+
│ │ ├── MeshPipe.ts # mesh instructions
|
|
67
|
+
│ │ ├── FilterPipe.ts # pooled filter push/pop instructions
|
|
68
|
+
│ │ ├── MaskPipe.ts # pooled mask push/pop instructions
|
|
69
|
+
│ │ ├── TextPipe.ts # offscreen text rasterization and texture upload
|
|
70
|
+
│ │ └── ParticlePipe.ts # particle rendering
|
|
71
|
+
│ ├── canvas/ # Canvas 2D backend and offscreen capture
|
|
72
|
+
│ │ ├── CanvasRenderer.ts # direct traversal with built-in filter approximations
|
|
73
|
+
│ │ ├── DisplayList.ts # offscreen cache for cacheAsBitmap
|
|
74
|
+
│ │ └── CanvasBuffer.ts # Canvas buffers and pixel hit testing
|
|
75
|
+
│ └── webgl/ # primary WebGL backend
|
|
76
|
+
│ ├── WebGLRenderer.ts # build/execute phases and render groups
|
|
77
|
+
│ ├── WebGLRenderContext.ts # WebGL state, draw scheduling and filter execution
|
|
78
|
+
│ ├── WebGLRenderBuffer.ts # pooled offscreen, stencil and scissor buffers
|
|
79
|
+
│ ├── WebGLRenderTarget.ts # framebuffer management
|
|
80
|
+
│ ├── WebGLVertexArrayObject.ts # single-texture 20B and multi-texture 24B vertex layouts
|
|
81
|
+
│ ├── WebGLDrawCmdManager.ts # 12 draw command types, including MULTI_TEXTURE
|
|
82
|
+
│ ├── WebGLProgram.ts # shader program cache
|
|
83
|
+
│ ├── WebGLUtils.ts # shader compilation, program creation, tint and texture helpers
|
|
84
|
+
│ ├── MultiTextureBatcher.ts # 8-texture batches and slotMap assignments
|
|
85
|
+
│ └── shaders/ # GLSL sources
|
|
86
|
+
│ ├── ShaderLib.ts # GLSL ES 1.00 for WebGL 1
|
|
87
|
+
│ └── ShaderLib2.ts # GLSL ES 3.00 for WebGL 2
|
|
88
|
+
├── events/ # event classes, EventPhase and IEventDispatcher
|
|
89
|
+
├── geom/ # Matrix, Point, Rectangle
|
|
90
|
+
├── filters/ # Blur, Glow, DropShadow, ColorMatrix, CustomFilter, MultiPassFilter, BloomFilter
|
|
91
|
+
├── text/ # text data and layout
|
|
92
|
+
│ ├── TextField.ts # rich text, input mode and password display
|
|
93
|
+
│ ├── BitmapText.ts # bitmap text
|
|
94
|
+
│ ├── BitmapFont.ts # bitmap font and texture ownership
|
|
95
|
+
│ ├── StageText.ts # DOM input for INPUT mode
|
|
96
|
+
│ ├── HtmlTextParser.ts # HTML text parsing
|
|
97
|
+
│ ├── InputController.ts # selection, caret and keyboard input
|
|
98
|
+
│ ├── TextMeasurer.ts # measureText and getFontString
|
|
99
|
+
│ ├── LineBreaks.ts # Unicode 17.0 UAX #14 boundaries and dictionary segmentation
|
|
100
|
+
│ ├── TextLineLayout.ts # rich-text wrapping, width fitting and UTF-16 source offsets
|
|
101
|
+
│ ├── WordWrap.ts # independent token and grapheme utilities
|
|
102
|
+
│ ├── enums/ # HorizontalAlign, VerticalAlign, TextFieldType, TextFieldInputType
|
|
103
|
+
│ └── types/ # ITextElement, IWTextElement, ILineElement, IHitTextElement
|
|
104
|
+
├── resource/ # resource management
|
|
105
|
+
│ ├── Resource.ts # resource manager, shared instance and async/await API
|
|
106
|
+
│ ├── ResourceConfig.ts # resource configuration
|
|
107
|
+
│ ├── ResourceEvent.ts # resource events
|
|
108
|
+
│ ├── ResourceItem.ts # resource items
|
|
109
|
+
│ ├── ResourceLoader.ts # resource loading queue
|
|
110
|
+
│ └── analyzers/ # AnalyzerBase, Image, Json, Sheet, Sound, Text and Font analyzers
|
|
111
|
+
├── system/ # environment capabilities
|
|
112
|
+
│ └── Capabilities.ts # runtime capabilities using UA and Client Hints
|
|
113
|
+
├── net/ # HttpRequest, ImageLoader, HttpMethod, HttpResponseType
|
|
114
|
+
├── media/ # Sound, SoundChannel, Video
|
|
115
|
+
├── utils/ # ByteArray, Timer, Logger, FontManager, DebugLog, Base64Util, NumberUtils, toColorString
|
|
116
|
+
│ # object identity uses === or WeakMap; no HashObject
|
|
117
|
+
├── localStorage/ # local storage functions
|
|
118
|
+
└── external/ # ExternalInterface
|
|
108
119
|
```
|
|
109
120
|
|
|
110
121
|
---
|
|
111
122
|
|
|
112
|
-
##
|
|
123
|
+
## 3. Rendering pipeline
|
|
113
124
|
|
|
114
|
-
### 3.1
|
|
125
|
+
### 3.1 Build and execute phases
|
|
115
126
|
|
|
116
127
|
```
|
|
117
|
-
Phase A — Build
|
|
118
|
-
|
|
128
|
+
Phase A — Build (structureDirty):
|
|
129
|
+
Traverse the display tree → create Instructions with transform snapshots → InstructionSet
|
|
119
130
|
|
|
120
|
-
Phase A' — Update
|
|
121
|
-
|
|
131
|
+
Phase A' — Update (renderDirty):
|
|
132
|
+
Visit dirtyRenderables → refresh transform snapshots using renderableIndex lookups
|
|
122
133
|
|
|
123
|
-
Phase B — Execute
|
|
124
|
-
|
|
134
|
+
Phase B — Execute (every frame):
|
|
135
|
+
Dispatch instructions to pipes without traversing the scene graph
|
|
125
136
|
```
|
|
126
137
|
|
|
127
|
-
### 3.2 RenderPipe
|
|
138
|
+
### 3.2 RenderPipe
|
|
128
139
|
|
|
129
140
|
```
|
|
130
141
|
RenderPipe<T extends DisplayObject>
|
|
131
|
-
├── addToInstructionSet(renderable, set)
|
|
132
|
-
├── updateRenderable(renderable)
|
|
133
|
-
└── destroyRenderable(renderable)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
├── BitmapPipe
|
|
137
|
-
├──
|
|
138
|
-
├──
|
|
139
|
-
├──
|
|
140
|
-
├──
|
|
141
|
-
├──
|
|
142
|
-
|
|
142
|
+
├── addToInstructionSet(renderable, set) — build instructions after structure changes
|
|
143
|
+
├── updateRenderable(renderable) — update visual data
|
|
144
|
+
└── destroyRenderable(renderable) — optional immediate cleanup; see texture GC below
|
|
145
|
+
|
|
146
|
+
Implementations:
|
|
147
|
+
├── BitmapPipe → BitmapInstruction → drawImage(), including scale9Grid
|
|
148
|
+
├── BitmapTextPipe → BitmapTextInstruction → shared layout → batched glyph drawImage()
|
|
149
|
+
├── GraphicsPipe → GraphicsInstruction → Canvas rasterization → texture upload → drawTexture()
|
|
150
|
+
├── MeshPipe → MeshInstruction → drawMesh()
|
|
151
|
+
├── TextPipe → TextInstruction → offscreen Canvas → texture upload → drawImage()
|
|
152
|
+
├── ParticlePipe → ParticleInstruction → particle batches
|
|
153
|
+
├── FilterPipe → FilterPush/Pop → offscreen FBO → shader effects
|
|
154
|
+
└── MaskPipe → MaskPush/Pop → stencil, scissor or offscreen compositing
|
|
143
155
|
```
|
|
144
156
|
|
|
145
|
-
**GPU
|
|
157
|
+
**GPU texture cleanup.** `WebGLRenderer` does not automatically call
|
|
158
|
+
`destroyRenderable()`. Display objects have no permanent-destruction signal:
|
|
159
|
+
`$onRemoveFromStage` also fires when an object is temporarily removed and later
|
|
160
|
+
reused. Releasing textures at that point would force repeated rasterization and
|
|
161
|
+
uploads, for example when virtual lists reuse renderers.
|
|
162
|
+
|
|
163
|
+
GraphicsPipe and TextPipe use `FinalizationRegistry` to call `gl.deleteTexture()`
|
|
164
|
+
when their Graphics/TextField owners are garbage-collected. Explicit
|
|
165
|
+
`destroyRenderable()` remains an optional immediate-release path; it unregisters
|
|
166
|
+
the GC callback to avoid duplicate deletion. BitmapPipe and MeshPipe have no
|
|
167
|
+
pipe-owned texture cleanup because their textures belong to BitmapData.
|
|
146
168
|
|
|
147
|
-
### 3.3
|
|
169
|
+
### 3.3 Render groups
|
|
148
170
|
|
|
149
171
|
```typescript
|
|
150
172
|
backgroundLayer.isRenderGroup = true;
|
|
151
173
|
```
|
|
152
174
|
|
|
153
|
-
-
|
|
154
|
-
-
|
|
155
|
-
-
|
|
156
|
-
-
|
|
157
|
-
-
|
|
158
|
-
-
|
|
175
|
+
- Each render group owns an InstructionSet.
|
|
176
|
+
- Its parent set contains one `renderGroup` instruction referencing that subtree.
|
|
177
|
+
- Structure changes inside the group rebuild its own set, not its parent's set.
|
|
178
|
+
- Static subtrees do not need to be traversed on every WebGL frame.
|
|
179
|
+
- A `WeakMap<DisplayObjectContainer, InstructionSet>` stores group sets.
|
|
180
|
+
- WeakRef tracks group lifetimes without preventing garbage collection.
|
|
159
181
|
|
|
160
|
-
### 3.4
|
|
182
|
+
### 3.4 Multi-texture batching
|
|
161
183
|
|
|
162
|
-
-
|
|
163
|
-
-
|
|
164
|
-
|
|
165
|
-
-
|
|
166
|
-
-
|
|
184
|
+
- MultiTextureBatcher manages up to 8 texture slots, the WebGL 1 minimum guarantee.
|
|
185
|
+
- The multi-texture vertex layout adds `aTextureId`, increasing the stride from
|
|
186
|
+
20 to 24 bytes.
|
|
187
|
+
- The fragment shader selects textures with an if/else chain for WebGL 1 support.
|
|
188
|
+
- Mesh, filter and blend changes flush the current batch when needed.
|
|
189
|
+
- WebGLVertexArrayObject maintains single-texture and multi-texture buffers and
|
|
190
|
+
grows GPU buffers as needed.
|
|
167
191
|
|
|
168
|
-
### 3.5
|
|
192
|
+
### 3.5 Dirty flags
|
|
169
193
|
|
|
170
194
|
```
|
|
171
|
-
DisplayObject
|
|
172
|
-
├── cacheDirty
|
|
173
|
-
├── renderDirty
|
|
174
|
-
└── renderMode
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
├── $onStructureChange?: () => void
|
|
178
|
-
├── $onRenderableDirty?: (obj: DisplayObject) => void
|
|
179
|
-
├── DisplayObjectContainer.$onContainerStructureChange?: (owner) => void
|
|
195
|
+
DisplayObject flags:
|
|
196
|
+
├── cacheDirty — invalidates cacheAsBitmap and propagates upward
|
|
197
|
+
├── renderDirty — visual changes (position, texture, alpha, tint), propagated upward
|
|
198
|
+
└── renderMode — NONE, FILTER, CLIP or SCROLLRECT
|
|
199
|
+
|
|
200
|
+
Notifications (single-Player static hooks installed by Player):
|
|
201
|
+
├── $onStructureChange?: () => void — structure changes
|
|
202
|
+
├── $onRenderableDirty?: (obj: DisplayObject) => void — visual changes
|
|
203
|
+
├── DisplayObjectContainer.$onContainerStructureChange?: (owner) => void
|
|
180
204
|
├── $markDirty()
|
|
181
|
-
│ ├──
|
|
182
|
-
│ ├──
|
|
183
|
-
│ └──
|
|
205
|
+
│ ├── refresh worldAlpha/worldTint caches for constant-time reads
|
|
206
|
+
│ ├── $onRenderableDirty?.(this) → WebGLRenderer.markRenderableDirty()
|
|
207
|
+
│ └── propagate cacheDirty and renderDirty upward
|
|
184
208
|
├── $updateRenderMode()
|
|
185
|
-
│ └──
|
|
209
|
+
│ └── $onStructureChange?.() → WebGLRenderer.markStructureDirty()
|
|
186
210
|
└── DisplayObjectContainer.markDirtyInternal()
|
|
187
|
-
└──
|
|
211
|
+
└── $onContainerStructureChange?.(this) → markStructureDirty(owner)
|
|
188
212
|
```
|
|
189
213
|
|
|
190
|
-
|
|
191
|
-
|
|
214
|
+
The engine supports one Player per page. Its constructor assigns these static
|
|
215
|
+
hooks to instance closures, and `destroy()` clears them. See `player/Player.ts`.
|
|
192
216
|
|
|
193
|
-
### 3.6 RenderObjectType
|
|
217
|
+
### 3.6 RenderObjectType dispatch
|
|
194
218
|
|
|
195
|
-
|
|
219
|
+
DisplayObject uses the `renderObjectType` enum to avoid `instanceof` checks on
|
|
220
|
+
hot rendering paths:
|
|
196
221
|
|
|
197
|
-
|
|
|
198
|
-
|
|
|
199
|
-
| `NONE`
|
|
200
|
-
| `BITMAP`
|
|
201
|
-
| `MESH`
|
|
202
|
-
| `SHAPE`
|
|
203
|
-
| `SPRITE`
|
|
204
|
-
| `TEXT`
|
|
205
|
-
| `PARTICLE`
|
|
222
|
+
| Enum | Value | Display type | Pipe |
|
|
223
|
+
| ------------- | ----- | ------------ | -------------- |
|
|
224
|
+
| `NONE` | 0 | No rendering | — |
|
|
225
|
+
| `BITMAP` | 1 | Bitmap | BitmapPipe |
|
|
226
|
+
| `MESH` | 2 | Mesh | MeshPipe |
|
|
227
|
+
| `SHAPE` | 3 | Shape | GraphicsPipe |
|
|
228
|
+
| `SPRITE` | 4 | Sprite | GraphicsPipe |
|
|
229
|
+
| `TEXT` | 5 | TextField | TextPipe |
|
|
230
|
+
| `PARTICLE` | 6 | Particle | ParticlePipe |
|
|
231
|
+
| `BITMAP_TEXT` | 7 | BitmapText | BitmapTextPipe |
|
|
206
232
|
|
|
207
233
|
---
|
|
208
234
|
|
|
209
|
-
##
|
|
235
|
+
## 4. WebGL backend
|
|
210
236
|
|
|
211
|
-
### 4.1 WebGL
|
|
237
|
+
### 4.1 WebGL selection
|
|
212
238
|
|
|
213
|
-
|
|
239
|
+
WebGLRenderContext selects a backend during initialization:
|
|
214
240
|
|
|
215
|
-
- **WebGL 2
|
|
216
|
-
- **WebGL 1
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
`
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
- 着色器库通过实例属性动态绑定:`ctx.shaders`、`ctx.blurTierFn`、`ctx.makeBlurH`、`ctx.makeBlurV`
|
|
241
|
+
- **WebGL 2 first:** `canvas.getContext('webgl2')` uses ShaderLib2 (GLSL ES 3.00).
|
|
242
|
+
- **WebGL 1 fallback:** `canvas.getContext('webgl')` uses ShaderLib (GLSL ES 1.00).
|
|
243
|
+
No `experimental-webgl` alias is used; the target browsers support `webgl`.
|
|
244
|
+
- **No separate probe canvas:** Player tries WebGL 2 and WebGL 1 directly on the
|
|
245
|
+
application's canvas, then falls back to Canvas 2D if both fail.
|
|
246
|
+
`checkWebGLSupport()` remains available to callers but is not used by Player.
|
|
247
|
+
- Shader helpers are selected through context properties: `ctx.shaders`,
|
|
248
|
+
`ctx.blurTierFn`, `ctx.makeBlurH` and `ctx.makeBlurV`.
|
|
224
249
|
|
|
225
|
-
### 4.2
|
|
250
|
+
### 4.2 Rendering flow
|
|
226
251
|
|
|
227
252
|
```
|
|
228
253
|
Player.render()
|
|
@@ -231,77 +256,97 @@ Player.render()
|
|
|
231
256
|
→ Phase B: _executeInstructions()
|
|
232
257
|
→ Pipe.execute() → WebGLRenderContext.drawImage/drawMesh/drawTexture()
|
|
233
258
|
→ WebGLRenderContext.flush() → _flush()
|
|
234
|
-
→
|
|
259
|
+
→ upload vertices with bufferSubData → visit DrawCmdManager → dispatch draw batches
|
|
235
260
|
```
|
|
236
261
|
|
|
237
|
-
### 4.3
|
|
238
|
-
|
|
239
|
-
|
|
|
240
|
-
|
|
|
241
|
-
| default_vert + texture_frag
|
|
242
|
-
| multi_vert + multi_frag
|
|
243
|
-
| default_vert + colorTransform_frag
|
|
244
|
-
| default_vert + glow_frag
|
|
245
|
-
| fullscreen_vert + makeBlurH/
|
|
246
|
-
| default_vert + primitive_frag
|
|
247
|
-
| fullscreen_vert
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
`texture()`
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
- **
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
- **
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
-
|
|
262
|
+
### 4.3 Shaders
|
|
263
|
+
|
|
264
|
+
| Shader | Purpose | Source |
|
|
265
|
+
| ---------------------------------- | --------------------------------------- | --------- |
|
|
266
|
+
| default_vert + texture_frag | Standard texture drawing | ShaderLib |
|
|
267
|
+
| multi_vert + multi_frag | Multi-texture batches, up to 8 textures | ShaderLib |
|
|
268
|
+
| default_vert + colorTransform_frag | ColorMatrixFilter | ShaderLib |
|
|
269
|
+
| default_vert + glow_frag | Glow/DropShadow | ShaderLib |
|
|
270
|
+
| fullscreen_vert + makeBlurH/VFrag | Horizontal/vertical blur in two passes | ShaderLib |
|
|
271
|
+
| default_vert + primitive_frag | Solid rectangles for stencil masks | ShaderLib |
|
|
272
|
+
| fullscreen_vert | Fullscreen quad blits for filter passes | ShaderLib |
|
|
273
|
+
|
|
274
|
+
ShaderLib2 supplies equivalent GLSL ES 3.00 shaders for WebGL 2, using `in`/`out`
|
|
275
|
+
instead of `attribute`/`varying`, and `texture()` instead of `texture2D()`.
|
|
276
|
+
Blur shaders use fixed loop limits of 4, 8, 16 or 32 samples with triangular weights.
|
|
277
|
+
|
|
278
|
+
### 4.4 Filters
|
|
279
|
+
|
|
280
|
+
FilterPipe emits paired push/pop instructions:
|
|
281
|
+
|
|
282
|
+
- **Push:** allocate an offscreen FBO with filter padding and redirect drawing.
|
|
283
|
+
- **Pop:** call `compositeFilterResult()` to composite the result into the parent.
|
|
284
|
+
|
|
285
|
+
The compositing sequence is:
|
|
286
|
+
|
|
287
|
+
1. Flush pending drawing to complete the captured input.
|
|
288
|
+
2. WebGLFilterSystem executes filters in array order. Intermediate passes disable
|
|
289
|
+
blending, stencil and scissor and write to separate targets.
|
|
290
|
+
3. Restore the parent FBO, viewport and clip state explicitly.
|
|
291
|
+
4. Composite with `drawFramebufferTexture()` without applying inherited alpha/tint
|
|
292
|
+
a second time.
|
|
293
|
+
5. Flush and return intermediate textures to the pool. Failures release resources
|
|
294
|
+
and queued commands so a later frame can recover.
|
|
295
|
+
|
|
296
|
+
- **ColorMatrixFilter:** an unmasked leaf with one filter and inherited resolution
|
|
297
|
+
can use the inline path; groups and combinations use offscreen targets.
|
|
298
|
+
- **BlurFilter:** horizontal/vertical separation, with quality controlling pass
|
|
299
|
+
pairs. Large radii downsample to stay within the 32-physical-pixel shader tier.
|
|
300
|
+
- **Glow/DropShadow:** retain glow_frag; knockout controls whether the source image
|
|
301
|
+
remains in the output.
|
|
302
|
+
- **CustomFilter:** explicit GLSL 100/300 sources, reflected numeric uniforms and
|
|
303
|
+
auxiliary BitmapData uploads with independent sampling.
|
|
304
|
+
- **MultiPassFilter/BloomFilter:** ordered acyclic pass graphs, with original or
|
|
305
|
+
earlier inputs and per-pass scaling.
|
|
306
|
+
|
|
307
|
+
WebGLFilterTargetPool caches up to 16 idle targets or 64 MiB. Subtree captures and
|
|
308
|
+
auxiliary images are outside this limit. WebGLFilterTextures manages auxiliary
|
|
309
|
+
image uploads and restoration. Shader programs are cached by GL context and source.
|
|
310
|
+
|
|
311
|
+
Filter-chain padding accumulates and includes child effects without changing
|
|
312
|
+
layout bounds. Offscreen passes use framebuffer UVs, with (0,0) at the lower left,
|
|
313
|
+
and preserve orientation. DropShadow angles reach shaders in radians. Auxiliary
|
|
314
|
+
DOM image bindings use UV transforms to account for vertical orientation.
|
|
315
|
+
|
|
316
|
+
See [GPU filters](filters.md) for APIs, examples, Canvas support and cache limits.
|
|
317
|
+
|
|
318
|
+
### 4.5 Masks
|
|
319
|
+
|
|
320
|
+
- Axis-aligned scrollRect/maskRect without an outer scissor uses scissor clipping.
|
|
321
|
+
- Rotated rectangles or rectangles inside an outer scissor use stencil clipping.
|
|
322
|
+
Both the WebGL canvas and capability checks request stencil without depth.
|
|
323
|
+
- DisplayObject masks use offscreen compositing with destination-in.
|
|
287
324
|
|
|
288
325
|
---
|
|
289
326
|
|
|
290
|
-
##
|
|
327
|
+
## 5. Canvas 2D backend
|
|
328
|
+
|
|
329
|
+
CanvasRenderer traverses the scene graph directly and supplies the fallback when
|
|
330
|
+
WebGL is unavailable. It also rasterizes offscreen caches and RenderTexture captures.
|
|
291
331
|
|
|
292
|
-
|
|
332
|
+
- Offscreen Graphics caching through `canvasCacheDirty`.
|
|
333
|
+
- CSS blur/drop-shadow approximations for Blur, DropShadow and Glow.
|
|
334
|
+
- CPU pixel processing for ColorMatrixFilter.
|
|
335
|
+
- DisplayList support for cacheAsBitmap.
|
|
336
|
+
- Pixel hit testing through a 3×3 offscreen buffer.
|
|
337
|
+
- Bitmap, Shape, Sprite, Mesh, TextField and BitmapText rendering.
|
|
338
|
+
- BitmapText draws atlas regions from shared layout, including trim offsets, tint
|
|
339
|
+
and ordinary clipping. See [bitmap fonts](bitmap-fonts.md) for ownership.
|
|
340
|
+
- TextField measurement, line layout and fillText/strokeText drawing. See
|
|
341
|
+
[text layout](./text-layout.md) for wrapping and source-offset contracts.
|
|
293
342
|
|
|
294
|
-
|
|
295
|
-
-
|
|
296
|
-
|
|
297
|
-
- cacheAsBitmap 支持(通过 DisplayList)
|
|
298
|
-
- 像素级命中测试(3x3 离屏 buffer,hitTestBuffer 函数)
|
|
299
|
-
- 支持所有 DisplayObject 类型:Bitmap, Shape, Sprite, Mesh, TextField(含样式、对齐、自动换行)
|
|
300
|
-
- TextField 渲染:测量 → 分行 → Canvas 2D fillText/strokeText 绘制;断行规则与输入偏移契约见 [text-layout.md](./text-layout.md)
|
|
343
|
+
CustomFilter, MultiPassFilter and BloomFilter are GPU effects and are skipped.
|
|
344
|
+
Built-in Canvas approximations are not pixel-equivalent to WebGL. The same
|
|
345
|
+
boundary applies to cacheAsTexture and RenderTexture capture.
|
|
301
346
|
|
|
302
347
|
---
|
|
303
348
|
|
|
304
|
-
##
|
|
349
|
+
## 6. Application startup
|
|
305
350
|
|
|
306
351
|
### `createPlayer(options)`
|
|
307
352
|
|
|
@@ -319,55 +364,56 @@ const app = createPlayer({
|
|
|
319
364
|
app.start(root);
|
|
320
365
|
```
|
|
321
366
|
|
|
322
|
-
`createPlayer`
|
|
367
|
+
`createPlayer` initializes:
|
|
323
368
|
|
|
324
|
-
1.
|
|
325
|
-
2.
|
|
326
|
-
3.
|
|
327
|
-
4.
|
|
369
|
+
1. Capabilities._init() for OS, isMobile and language detection.
|
|
370
|
+
2. RenderTexture.renderer on first use, providing offscreen Canvas 2D rendering.
|
|
371
|
+
3. Stage, Player, TouchHandler and ScreenAdapter, preferring WebGL with Canvas fallback.
|
|
372
|
+
4. setupLifecycle(stage) for ENTER_FRAME and RENDER broadcasts.
|
|
328
373
|
|
|
329
374
|
### KurotOptions
|
|
330
375
|
|
|
331
|
-
|
|
|
332
|
-
| --------------- | ------------------- |
|
|
333
|
-
| `canvas` | `HTMLCanvasElement` |
|
|
334
|
-
| `frameRate` | `number` | `60`
|
|
335
|
-
| `scaleMode` | `StageScaleMode` | `'showAll'`
|
|
336
|
-
| `contentWidth` | `number` | `canvas.width`
|
|
337
|
-
| `contentHeight` | `number` | `canvas.height` |
|
|
338
|
-
| `resolution` | `number` | `min(DPR, 2)`
|
|
339
|
-
| `orientation` | `OrientationMode` | `'auto'`
|
|
340
|
-
| `maxTouches` | `number` | `99`
|
|
341
|
-
| `background` | `string` | —
|
|
342
|
-
|
|
343
|
-
### KurotApp
|
|
344
|
-
|
|
345
|
-
|
|
|
346
|
-
| --------------- |
|
|
347
|
-
| `player` | `Player`
|
|
348
|
-
| `stage` | `Stage`
|
|
349
|
-
| `touchHandler` | `TouchHandler`
|
|
350
|
-
| `screenAdapter` | `ScreenAdapter`
|
|
351
|
-
| `start(root?)` | `() => void`
|
|
352
|
-
| `stop()` | `() => void`
|
|
376
|
+
| Property | Type | Default | Description |
|
|
377
|
+
| --------------- | ------------------- | ------------------------- | --------------------------- |
|
|
378
|
+
| `canvas` | `HTMLCanvasElement` | Required | Rendering canvas |
|
|
379
|
+
| `frameRate` | `number` | `60` | Target frame rate |
|
|
380
|
+
| `scaleMode` | `StageScaleMode` | `'showAll'` | Screen scale mode |
|
|
381
|
+
| `contentWidth` | `number` | `canvas.width` or `640` | Logical content width |
|
|
382
|
+
| `contentHeight` | `number` | `canvas.height` or `1136` | Logical content height |
|
|
383
|
+
| `resolution` | `number` | `min(DPR, 2)` | Backing-store pixel density |
|
|
384
|
+
| `orientation` | `OrientationMode` | `'auto'` | Screen orientation |
|
|
385
|
+
| `maxTouches` | `number` | `99` | Maximum touch points |
|
|
386
|
+
| `background` | `string` | — | CSS background color |
|
|
387
|
+
|
|
388
|
+
### KurotApp
|
|
389
|
+
|
|
390
|
+
| Property | Type | Description |
|
|
391
|
+
| --------------- | -------------------------------- | ------------------------------------------------------ |
|
|
392
|
+
| `player` | `Player` | Renderer and game loop |
|
|
393
|
+
| `stage` | `Stage` | Scene root |
|
|
394
|
+
| `touchHandler` | `TouchHandler` | Touch and mouse input |
|
|
395
|
+
| `screenAdapter` | `ScreenAdapter` | Screen adaptation |
|
|
396
|
+
| `start(root?)` | `(root?: DisplayObject) => void` | Start or resume the game loop |
|
|
397
|
+
| `stop()` | `() => void` | Stop the loop; it can be resumed |
|
|
398
|
+
| `destroy()` | `() => void` | Release the player, input, adapter and lifecycle hooks |
|
|
353
399
|
|
|
354
400
|
---
|
|
355
401
|
|
|
356
|
-
##
|
|
357
|
-
|
|
358
|
-
`test
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
|
362
|
-
|
|
|
363
|
-
| events/
|
|
364
|
-
| geom/
|
|
365
|
-
| utils/
|
|
366
|
-
| display/
|
|
367
|
-
| filters/
|
|
368
|
-
| media/
|
|
369
|
-
| player/
|
|
370
|
-
| net/
|
|
371
|
-
| resource/
|
|
372
|
-
| examples/benchmark/tests/ |
|
|
373
|
-
| text/
|
|
402
|
+
## 7. Test coverage
|
|
403
|
+
|
|
404
|
+
Tests are organized by module in `test/`. Run `pnpm --dir packages/core test` for
|
|
405
|
+
current file and test counts.
|
|
406
|
+
|
|
407
|
+
| Module | Main coverage |
|
|
408
|
+
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
409
|
+
| events/ | Event, EventDispatcher, EventPropagation, EventMap, TouchEvent, HTTPStatusEvent, ProgressEvent |
|
|
410
|
+
| geom/ | Matrix, Point, Rectangle |
|
|
411
|
+
| utils/ | ByteArray, Base64Util, Logger, DebugLog, NumberUtils, toColorString |
|
|
412
|
+
| display/ | DisplayObject, DisplayObjectContainer, DisplayObjectIntegration, Bitmap, BitmapData, Sprite, Shape, Mesh, Stage, StageText, Graphics, Texture, SpriteSheet, BlendMode, DisplayList |
|
|
413
|
+
| filters/ | Filter classes, CustomFilter, filter integration and offscreen effect transforms |
|
|
414
|
+
| media/ | Sound, SoundChannel, Video |
|
|
415
|
+
| player/ | InstructionSet, InstructionPool, RenderGroup, TextPipe, MaskPipe, WebGLRendererDirty, WebGLRendererLeaf, WebGLVertexArrayObject, WebGLRenderBuffer, WebGLBlurFramebufferPool, CreatePlayer, TouchHandler |
|
|
416
|
+
| net/ | HttpRequest, ImageLoader |
|
|
417
|
+
| resource/ | Resource group serialization; ResourceLoader concurrency, retries and missing analyzers; FontAnalyzer loading and ownership |
|
|
418
|
+
| examples/benchmark/tests/ | Benchmark runtime and cross-engine comparisons |
|
|
419
|
+
| text/ | Display integration, BitmapText layout and native glyph geometry |
|