spine-html 0.4.1 → 0.5.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/NOTICE.md +4 -3
- package/README.md +141 -3
- package/dist/MeshGlBlitter.d.ts +43 -1
- package/dist/MeshGlBlitter.d.ts.map +1 -1
- package/dist/MeshGlBlitter.js +85 -8
- package/dist/MeshGlBlitter.js.map +1 -1
- package/dist/SpineHtmlRenderer.d.ts +121 -7
- package/dist/SpineHtmlRenderer.d.ts.map +1 -1
- package/dist/SpineHtmlRenderer.js +265 -30
- package/dist/SpineHtmlRenderer.js.map +1 -1
- package/dist/binary.d.ts +48 -0
- package/dist/binary.d.ts.map +1 -0
- package/dist/binary.js +29 -0
- package/dist/binary.js.map +1 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/loadAtlasAssets.d.ts +73 -0
- package/dist/loadAtlasAssets.d.ts.map +1 -0
- package/dist/loadAtlasAssets.js +75 -0
- package/dist/loadAtlasAssets.js.map +1 -0
- package/dist/loadSkeletonAssets.d.ts +41 -22
- package/dist/loadSkeletonAssets.d.ts.map +1 -1
- package/dist/loadSkeletonAssets.js +48 -49
- package/dist/loadSkeletonAssets.js.map +1 -1
- package/dist/main.js +8 -3
- package/dist/main.js.map +1 -1
- package/package.json +5 -1
package/NOTICE.md
CHANGED
|
@@ -14,6 +14,7 @@ redistribution includes the Spine Runtimes license and copyright notice.
|
|
|
14
14
|
|
|
15
15
|
## Example assets
|
|
16
16
|
|
|
17
|
-
The spineboy skeleton, atlas, and images used by the demo
|
|
18
|
-
Software. They are **not redistributed** in this
|
|
19
|
-
downloads them from the official spine-runtimes
|
|
17
|
+
The spineboy skeleton exports (JSON and binary), atlas, and images used by the demo
|
|
18
|
+
and the tests are owned by Esoteric Software. They are **not redistributed** in this
|
|
19
|
+
repository; `scripts/fetch-assets.sh` downloads them from the official spine-runtimes
|
|
20
|
+
repository for local evaluation.
|
package/README.md
CHANGED
|
@@ -148,12 +148,78 @@ assets.dispose();
|
|
|
148
148
|
`spine-html` is a third-party renderer and is not affiliated with or endorsed by
|
|
149
149
|
Esoteric Software.
|
|
150
150
|
|
|
151
|
+
### One atlas, several skeletons
|
|
152
|
+
|
|
153
|
+
Skeletons that share an atlas — a character's `-ess` and `-pro` exports, a whole
|
|
154
|
+
cast packed onto one page — load in two steps instead. Calling
|
|
155
|
+
`loadSkeletonAssets` once per skeleton would fetch and unpack the same pages
|
|
156
|
+
again and mint a second set of region blob URLs:
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
import { loadAtlasAssets, loadSkeletonJson, SpineHtmlRenderer } from 'spine-html';
|
|
160
|
+
|
|
161
|
+
const shared = await loadAtlasAssets({ atlasUrl: '/spineboy/spineboy.atlas' });
|
|
162
|
+
const [essData, proData] = await Promise.all([
|
|
163
|
+
loadSkeletonJson(shared, '/spineboy/spineboy-ess.json'),
|
|
164
|
+
loadSkeletonJson(shared, '/spineboy/spineboy-pro.json'),
|
|
165
|
+
]);
|
|
166
|
+
|
|
167
|
+
const ess = new SpineHtmlRenderer(essRoot, shared.regionImages);
|
|
168
|
+
const pro = new SpineHtmlRenderer(proRoot, shared.regionImages);
|
|
169
|
+
|
|
170
|
+
// Unloading: every renderer first, then the one dispose() that owns the bitmaps.
|
|
171
|
+
ess.dispose();
|
|
172
|
+
pro.dispose();
|
|
173
|
+
shared.dispose();
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
`loadAtlasAssets` takes the atlas half of the options above (`resolvePage`,
|
|
177
|
+
`crossOrigin`, `fetch`) and `loadSkeletonJson` the skeleton half (`scale`,
|
|
178
|
+
`fetch`). Ownership is the thing to keep straight: the atlas assets belong to
|
|
179
|
+
the caller, reading a skeleton against them never frees them, and one
|
|
180
|
+
`regionImages` map is meant to be handed to several renderers — so there is
|
|
181
|
+
exactly one `dispose()` for however many skeletons were read. `loadSkeletonJson`
|
|
182
|
+
asks only for `{ atlas }`, so a caller that built its atlas by hand (below) can
|
|
183
|
+
still use it for the read. `loadSkeletonAssets` is these two calls with the
|
|
184
|
+
atlas half kept private: use it for one atlas and one skeleton, this for the
|
|
185
|
+
rest.
|
|
186
|
+
|
|
187
|
+
### Binary exports (`.skel`)
|
|
188
|
+
|
|
189
|
+
Binary exports are read by a second parser, `SkeletonBinary`, which is as big as
|
|
190
|
+
the JSON one. It lives behind its own entry point so that consumers who only
|
|
191
|
+
ever read `.json` never carry it:
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
import { loadAtlasAssets, SpineHtmlRenderer } from 'spine-html';
|
|
195
|
+
import { loadSkeletonBinary } from 'spine-html/binary';
|
|
196
|
+
|
|
197
|
+
const shared = await loadAtlasAssets({ atlasUrl: '/spineboy/spineboy.atlas' });
|
|
198
|
+
const data = await loadSkeletonBinary(shared, '/spineboy/spineboy-pro.skel');
|
|
199
|
+
|
|
200
|
+
const renderer = new SpineHtmlRenderer(rootElement, shared.regionImages);
|
|
201
|
+
// Unloading, as above: renderer.dispose(); shared.dispose();
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
`loadSkeletonBinary` is `loadSkeletonJson` with the parser swapped: same
|
|
205
|
+
arguments, the same `{ scale, fetch }` options, the same ownership rule — it
|
|
206
|
+
never frees `assets`, whichever way it ends. Those two calls are the binary path
|
|
207
|
+
in full. There is no one-call `loadSkeletonAssetsBinary`, because the atlas half
|
|
208
|
+
is precisely what a caller reading binary usually wants kept in hand, and hiding
|
|
209
|
+
it again would only earn back a line.
|
|
210
|
+
|
|
211
|
+
The subpath is the whole mechanism, so import it as written: pulling
|
|
212
|
+
`loadSkeletonBinary` out of `'spine-html'` is not possible, by design. Worth
|
|
213
|
+
knowing about the format itself: binary exports are version-locked to the
|
|
214
|
+
runtime that reads them, so a `.skel` written by an editor newer than your
|
|
215
|
+
installed `@esotericsoftware/spine-core` fails in the read, not in the fetch.
|
|
216
|
+
|
|
151
217
|
### Loading it yourself
|
|
152
218
|
|
|
153
219
|
`loadSkeletonAssets` is optional sugar over five `spine-core` calls, and the
|
|
154
220
|
package works without it. Drop to the low-level path whenever you need
|
|
155
|
-
something
|
|
156
|
-
|
|
221
|
+
something no loader does — images that are already in memory, an atlas that is
|
|
222
|
+
not fetched from a URL at all:
|
|
157
223
|
|
|
158
224
|
```ts
|
|
159
225
|
import { TextureAtlas, AtlasAttachmentLoader, SkeletonJson }
|
|
@@ -181,6 +247,35 @@ it — and calling it twice is a no-op. Load once for the page's lifetime and yo
|
|
|
181
247
|
can ignore it; load and unload repeatedly without it and you leak an atlas per
|
|
182
248
|
cycle.
|
|
183
249
|
|
|
250
|
+
### What unloading frees
|
|
251
|
+
|
|
252
|
+
`revokeRegions()` — and `assets.dispose()`, which just calls it — frees the blob
|
|
253
|
+
URLs `unpackRegions` minted, and nothing else. The rest is pinned by objects you
|
|
254
|
+
own: an atlas **page image** is held by the `DomTexture` you attached to its
|
|
255
|
+
page, and `SkeletonData` reaches that same image through every attachment
|
|
256
|
+
(`region.texture.getImage()`), so a page is released only once the atlas, the
|
|
257
|
+
skeleton data and every renderer drawing from them are gone. `atlas.dispose()`
|
|
258
|
+
does not do it — `DomTexture.dispose()` is a no-op, because the image is yours.
|
|
259
|
+
With the `webgl` mesh backend the shared blitter also uploads each page image on
|
|
260
|
+
first use, but that GL texture is not the module's forever: every renderer
|
|
261
|
+
drawing the page holds a reference to it, `renderer.dispose()` hands those back,
|
|
262
|
+
and the texture is deleted once the last renderer using that page is disposed —
|
|
263
|
+
a later frame that needs the page uploads it again. The cache is keyed weakly by
|
|
264
|
+
the page image, so a renderer dropped without `dispose()` costs GPU memory until
|
|
265
|
+
the context is lost, but never keeps the image itself alive.
|
|
266
|
+
|
|
267
|
+
A meshed skeleton samples the page bitmap every frame, so its decoded form stays
|
|
268
|
+
in use: a floor on the order of `page width × page height × 4` bytes per page —
|
|
269
|
+
1 MiB for spineboy's single 1024×256 page. A rigid-only skeleton draws nothing
|
|
270
|
+
from the page after `unpackRegions`, and what a merely reachable, undrawn image
|
|
271
|
+
costs is up to the browser, not measurable from script.
|
|
272
|
+
|
|
273
|
+
Unload in this order:
|
|
274
|
+
|
|
275
|
+
1. `renderer.dispose()`, for every renderer using the images.
|
|
276
|
+
2. `revokeRegions(regionImages)` (or `assets.dispose()`).
|
|
277
|
+
3. Drop your references to the atlas and the skeleton data.
|
|
278
|
+
|
|
184
279
|
### One part per page (loose part PNGs)
|
|
185
280
|
|
|
186
281
|
Not every pipeline runs the Spine editor's texture packer. If your parts are
|
|
@@ -227,10 +322,28 @@ const renderer = new SpineHtmlRenderer(rootElement, regionImages);
|
|
|
227
322
|
raster matches the screen: `devicePixelRatio * rootScale`). **Writing it
|
|
228
323
|
reallocates every mesh canvas backing store on the next frame**, and each
|
|
229
324
|
reallocation recreates a GPU surface — the cost that took real Safari to ~3 fps
|
|
230
|
-
when it happened per frame.
|
|
325
|
+
when it happened per frame. Each canvas is then sized from what the new ratio
|
|
326
|
+
needs, in both directions: lowering the ratio gives the backing pixels back
|
|
327
|
+
(the backing is grow-only *within* a ratio, not across a change of one). Set
|
|
328
|
+
it when a layout settles, never per frame:
|
|
231
329
|
debounce resize drags and quantize the value instead of tracking it
|
|
232
330
|
continuously. `renderer.canvasReallocCount` is the check — it must fall back to
|
|
233
331
|
zero within a second or two.
|
|
332
|
+
- `renderer.syncPixelRatio()` — measures the root's effective on-screen scale
|
|
333
|
+
and sets `pixelRatio` to `devicePixelRatio × scale`, returning the ratio now
|
|
334
|
+
in effect. It appends a hidden 100 px box to the root, reads its box once and
|
|
335
|
+
removes it (the root itself is usually 0×0), so it is **one forced layout per
|
|
336
|
+
call** — which is exactly why the renderer never calls it for you: there is no
|
|
337
|
+
per-frame layout read anywhere in this library. Call it when a zoom or a
|
|
338
|
+
layout *settles* (gesture end, debounced resize), not during the drag. A
|
|
339
|
+
change under 0.1% is ignored, so layout jitter cannot churn GPU surfaces, and
|
|
340
|
+
a root that is not laid out (a `display: none` ancestor) leaves the ratio
|
|
341
|
+
alone. Under an ancestor rotation the measured box is inflated and the ratio
|
|
342
|
+
errs high — oversampling costs pixels, undersampling costs picture.
|
|
343
|
+
- `renderer.meshBackingPixels` — allocated mesh-canvas backing pixels
|
|
344
|
+
(Σ width × height), computed on demand. This is what `pixelRatio` moves
|
|
345
|
+
quadratically, and the cheapest way to see an oversampling stage; the demo
|
|
346
|
+
prints it in the stats line as `backing N Mpx`.
|
|
234
347
|
- `renderer.meshBackend` — `'canvas2d'` (default) or `'webgl'`; same output, but
|
|
235
348
|
heavy deforming scenes on Safari want `'webgl'` (see Measured above). Falls back
|
|
236
349
|
to canvas2d automatically when WebGL is unavailable. Switching re-rasters every
|
|
@@ -238,6 +351,22 @@ const renderer = new SpineHtmlRenderer(rootElement, regionImages);
|
|
|
238
351
|
- `renderer.triangleExpand` — clip overdraw in px that closes antialiased mesh
|
|
239
352
|
seams (default 0.5). Also re-rasters every mesh once when changed.
|
|
240
353
|
|
|
354
|
+
**A zoomable stage.** The mesh tier rasters at `world × pixelRatio` in the
|
|
355
|
+
root's own coordinates, and it cannot see a CSS transform above the root — so
|
|
356
|
+
the most natural pan/zoom stage, `transform: scale(zoom)` on an ancestor, makes
|
|
357
|
+
it oversample by `1/zoom²` in backing pixels until the zoom is folded in. The
|
|
358
|
+
picture stays correct throughout, which is what makes this easy to ship: only
|
|
359
|
+
the allocation and the frame rate move. Call `syncPixelRatio()` when the zoom
|
|
360
|
+
settles, or set `pixelRatio = devicePixelRatio * zoom` yourself. Measured
|
|
361
|
+
on-device (Chromium, dpr 2, stage under `scale(0.25)`, ~2.2 M CSS px on screen):
|
|
362
|
+
|
|
363
|
+
| scene | `pixelRatio` | `meshBackingPixels` | fps |
|
|
364
|
+
| --- | --- | --- | --- |
|
|
365
|
+
| 57 meshes | `devicePixelRatio` (2) | 139.1 Mpx | 14–21 |
|
|
366
|
+
| 57 meshes | `dpr × zoom` (0.5) | 9.1 Mpx | 61 |
|
|
367
|
+
| 92 meshes | `devicePixelRatio` (2) | 141.1 Mpx | 36–39 |
|
|
368
|
+
| 92 meshes | `dpr × zoom` (0.5) | 9.1 Mpx | 60–61 |
|
|
369
|
+
|
|
241
370
|
## Demo (this repository)
|
|
242
371
|
|
|
243
372
|
```bash
|
|
@@ -282,6 +411,15 @@ resolving, so blob ownership — every unpacked URL freed, nothing the caller
|
|
|
282
411
|
owns touched, nothing stranded by a failed load — is asserted rather than
|
|
283
412
|
assumed.
|
|
284
413
|
|
|
414
|
+
The server is part of the test: a run tests whatever is being served on its
|
|
415
|
+
port. Two checkouts of this repository on one machine (a worktree, a second
|
|
416
|
+
clone) default to the same port 4321 and reuse an existing server, so the
|
|
417
|
+
second run quietly tests the first one's build — green, and about the wrong
|
|
418
|
+
tree. Give each concurrent checkout its own port with `TEST_PORT`
|
|
419
|
+
(`TEST_PORT=4333 bun run test`); setting it also disables server reuse, so a
|
|
420
|
+
busy port fails the run instead of being borrowed. Unset, nothing changes:
|
|
421
|
+
port 4321, reuse unless `CI`.
|
|
422
|
+
|
|
285
423
|
Standing rule: **headless numbers are never Safari performance evidence** —
|
|
286
424
|
nothing in the suite asserts timing, and headless-WebKit fps/ms readings do
|
|
287
425
|
not transfer (software rasterizer, measured up to 28× off real Safari). The
|
package/dist/MeshGlBlitter.d.ts
CHANGED
|
@@ -20,6 +20,13 @@
|
|
|
20
20
|
* preserveDrawingBuffer nor cross-frame content is relied on. The buffer
|
|
21
21
|
* grows quantized and never shrinks, mirroring the per-part backing policy
|
|
22
22
|
* (reallocating GPU surfaces per frame is a Safari killer).
|
|
23
|
+
*
|
|
24
|
+
* Page textures are the one thing here with a lifetime, and since this object
|
|
25
|
+
* outlives every renderer they are reference-counted: a renderer retains each
|
|
26
|
+
* page it queues a job for and releases them in dispose(), and the last
|
|
27
|
+
* release deletes the GL texture (a later job re-uploads it). The cache is
|
|
28
|
+
* keyed weakly by the page image, so a consumer that never disposes still
|
|
29
|
+
* loses nothing but GPU memory — this object never pins the caller's image.
|
|
23
30
|
*/
|
|
24
31
|
export interface MeshBlitJob {
|
|
25
32
|
/** Destination per-part canvas; the blit clears its full backing first. */
|
|
@@ -40,10 +47,22 @@ export interface MeshBlitJob {
|
|
|
40
47
|
}
|
|
41
48
|
declare class MeshGlBlitter {
|
|
42
49
|
lost: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Page textures created minus deleted, i.e. how many uploads are live right
|
|
52
|
+
* now. Deterministic (no GC in the path), which is what the lifetime tests
|
|
53
|
+
* assert against — see tests/gl-textures.spec.ts.
|
|
54
|
+
*/
|
|
55
|
+
liveTextureCount: number;
|
|
43
56
|
private readonly canvas;
|
|
44
57
|
private readonly gl;
|
|
45
58
|
private readonly uResolution;
|
|
46
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Weak by the page image on purpose: a consumer that forgets dispose()
|
|
61
|
+
* leaks its texture until context loss, but dropping the image still lets
|
|
62
|
+
* the image (and then the WebGLTexture this entry holds) be collected.
|
|
63
|
+
* Reassigned wholesale on context loss, never iterated.
|
|
64
|
+
*/
|
|
65
|
+
private textures;
|
|
47
66
|
private readonly maxSize;
|
|
48
67
|
private vertexData;
|
|
49
68
|
/** Per-job packed rect origins, filled by flush(). */
|
|
@@ -56,6 +75,29 @@ declare class MeshGlBlitter {
|
|
|
56
75
|
* cannot fit) so the caller can rasterize the batch on the canvas2d path.
|
|
57
76
|
*/
|
|
58
77
|
flush(jobs: MeshBlitJob[]): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Declares one more user of `page`. The upload itself stays lazy (the first
|
|
80
|
+
* flush that binds the page does it) — this only counts, so that the last
|
|
81
|
+
* release() can free the texture instead of the module holding it forever.
|
|
82
|
+
* Callers retain once per page and hand the same page back exactly once;
|
|
83
|
+
* SpineHtmlRenderer keeps that ledger and settles it in dispose().
|
|
84
|
+
*/
|
|
85
|
+
retain(page: HTMLImageElement): void;
|
|
86
|
+
/**
|
|
87
|
+
* Gives back one retain(). The GL texture goes when the last user of the
|
|
88
|
+
* page is gone; a later job for the same page simply uploads it again. A
|
|
89
|
+
* page the cache does not know (a release after a context loss dropped
|
|
90
|
+
* everything, or a double dispose) is a no-op, so this is safe to call
|
|
91
|
+
* unconditionally.
|
|
92
|
+
*/
|
|
93
|
+
release(page: HTMLImageElement): void;
|
|
94
|
+
/**
|
|
95
|
+
* Context loss invalidates every texture handle at once. Drop the cache and
|
|
96
|
+
* the count instead of carrying dead handles (deleting them is pointless —
|
|
97
|
+
* the GPU side is already gone) and let the next frames re-upload if the
|
|
98
|
+
* caller keeps drawing; the renderer meanwhile falls back to canvas2d.
|
|
99
|
+
*/
|
|
100
|
+
private markLost;
|
|
59
101
|
private compile;
|
|
60
102
|
private textureFor;
|
|
61
103
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MeshGlBlitter.d.ts","sourceRoot":"","sources":["../src/MeshGlBlitter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"MeshGlBlitter.d.ts","sourceRoot":"","sources":["../src/MeshGlBlitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,MAAM,WAAW,WAAW;IAC1B,2EAA2E;IAC3E,MAAM,EAAE,iBAAiB,CAAC;IAC1B,+EAA+E;IAC/E,IAAI,EAAE,gBAAgB,CAAC;IACvB,mFAAmF;IACnF,QAAQ,EAAE,YAAY,CAAC;IACvB,mDAAmD;IACnD,GAAG,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACvB,gDAAgD;IAChD,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAC7B,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAoCD,cAAM,aAAa;IACjB,IAAI,UAAS;IACb;;;;OAIG;IACH,gBAAgB,SAAK;IAErB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;IAC3D,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAwB;IAC3C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;IACnD;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAgD;IAChE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,UAAU,CAA0B;IAC5C,sDAAsD;IACtD,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,KAAK,CAAgB;;IAoD7B;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,OAAO;IAwGnC;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAMpC;;;;;;OAMG;IACH,OAAO,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAarC;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,UAAU;CA6BnB;AAID;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,GAAG,IAAI,CASvD"}
|
package/dist/MeshGlBlitter.js
CHANGED
|
@@ -20,6 +20,13 @@
|
|
|
20
20
|
* preserveDrawingBuffer nor cross-frame content is relied on. The buffer
|
|
21
21
|
* grows quantized and never shrinks, mirroring the per-part backing policy
|
|
22
22
|
* (reallocating GPU surfaces per frame is a Safari killer).
|
|
23
|
+
*
|
|
24
|
+
* Page textures are the one thing here with a lifetime, and since this object
|
|
25
|
+
* outlives every renderer they are reference-counted: a renderer retains each
|
|
26
|
+
* page it queues a job for and releases them in dispose(), and the last
|
|
27
|
+
* release deletes the GL texture (a later job re-uploads it). The cache is
|
|
28
|
+
* keyed weakly by the page image, so a consumer that never disposes still
|
|
29
|
+
* loses nothing but GPU memory — this object never pins the caller's image.
|
|
23
30
|
*/
|
|
24
31
|
const VERTEX_SHADER = `
|
|
25
32
|
attribute vec2 aPos;
|
|
@@ -46,10 +53,22 @@ const GUTTER = 1;
|
|
|
46
53
|
const GROW_STEP = 256;
|
|
47
54
|
class MeshGlBlitter {
|
|
48
55
|
lost = false;
|
|
56
|
+
/**
|
|
57
|
+
* Page textures created minus deleted, i.e. how many uploads are live right
|
|
58
|
+
* now. Deterministic (no GC in the path), which is what the lifetime tests
|
|
59
|
+
* assert against — see tests/gl-textures.spec.ts.
|
|
60
|
+
*/
|
|
61
|
+
liveTextureCount = 0;
|
|
49
62
|
canvas = document.createElement('canvas');
|
|
50
63
|
gl;
|
|
51
64
|
uResolution;
|
|
52
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Weak by the page image on purpose: a consumer that forgets dispose()
|
|
67
|
+
* leaks its texture until context loss, but dropping the image still lets
|
|
68
|
+
* the image (and then the WebGLTexture this entry holds) be collected.
|
|
69
|
+
* Reassigned wholesale on context loss, never iterated.
|
|
70
|
+
*/
|
|
71
|
+
textures = new WeakMap();
|
|
53
72
|
maxSize;
|
|
54
73
|
vertexData = new Float32Array(8192);
|
|
55
74
|
/** Per-job packed rect origins, filled by flush(). */
|
|
@@ -70,7 +89,7 @@ class MeshGlBlitter {
|
|
|
70
89
|
// No restore attempt: on loss the renderer falls back to canvas2d and the
|
|
71
90
|
// backend signature re-dirties every mesh, so frames stay complete.
|
|
72
91
|
this.canvas.addEventListener('webglcontextlost', () => {
|
|
73
|
-
this.
|
|
92
|
+
this.markLost();
|
|
74
93
|
});
|
|
75
94
|
const program = gl.createProgram();
|
|
76
95
|
if (!program)
|
|
@@ -194,7 +213,7 @@ class MeshGlBlitter {
|
|
|
194
213
|
// If the context died mid-batch the draws above were no-ops; report it
|
|
195
214
|
// before blitting stale/blank rects onto the part canvases.
|
|
196
215
|
if (gl.isContextLost()) {
|
|
197
|
-
this.
|
|
216
|
+
this.markLost();
|
|
198
217
|
return false;
|
|
199
218
|
}
|
|
200
219
|
// Blit each rect onto its per-part canvas: same-task read (no
|
|
@@ -211,6 +230,54 @@ class MeshGlBlitter {
|
|
|
211
230
|
}
|
|
212
231
|
return true;
|
|
213
232
|
}
|
|
233
|
+
/**
|
|
234
|
+
* Declares one more user of `page`. The upload itself stays lazy (the first
|
|
235
|
+
* flush that binds the page does it) — this only counts, so that the last
|
|
236
|
+
* release() can free the texture instead of the module holding it forever.
|
|
237
|
+
* Callers retain once per page and hand the same page back exactly once;
|
|
238
|
+
* SpineHtmlRenderer keeps that ledger and settles it in dispose().
|
|
239
|
+
*/
|
|
240
|
+
retain(page) {
|
|
241
|
+
const entry = this.textures.get(page);
|
|
242
|
+
if (entry)
|
|
243
|
+
entry.users++;
|
|
244
|
+
else
|
|
245
|
+
this.textures.set(page, { texture: null, users: 1 });
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Gives back one retain(). The GL texture goes when the last user of the
|
|
249
|
+
* page is gone; a later job for the same page simply uploads it again. A
|
|
250
|
+
* page the cache does not know (a release after a context loss dropped
|
|
251
|
+
* everything, or a double dispose) is a no-op, so this is safe to call
|
|
252
|
+
* unconditionally.
|
|
253
|
+
*/
|
|
254
|
+
release(page) {
|
|
255
|
+
const entry = this.textures.get(page);
|
|
256
|
+
if (!entry)
|
|
257
|
+
return;
|
|
258
|
+
if (--entry.users > 0)
|
|
259
|
+
return;
|
|
260
|
+
this.textures.delete(page);
|
|
261
|
+
if (!entry.texture)
|
|
262
|
+
return;
|
|
263
|
+
// deleteTexture is a documented no-op on a lost context rather than a
|
|
264
|
+
// throw, but a lost context has already dropped the cache and zeroed the
|
|
265
|
+
// count — reaching here with `lost` set would mean decrementing twice.
|
|
266
|
+
if (!this.lost && !this.gl.isContextLost())
|
|
267
|
+
this.gl.deleteTexture(entry.texture);
|
|
268
|
+
this.liveTextureCount--;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Context loss invalidates every texture handle at once. Drop the cache and
|
|
272
|
+
* the count instead of carrying dead handles (deleting them is pointless —
|
|
273
|
+
* the GPU side is already gone) and let the next frames re-upload if the
|
|
274
|
+
* caller keeps drawing; the renderer meanwhile falls back to canvas2d.
|
|
275
|
+
*/
|
|
276
|
+
markLost() {
|
|
277
|
+
this.lost = true;
|
|
278
|
+
this.textures = new WeakMap();
|
|
279
|
+
this.liveTextureCount = 0;
|
|
280
|
+
}
|
|
214
281
|
compile(type, source) {
|
|
215
282
|
const gl = this.gl;
|
|
216
283
|
const shader = gl.createShader(type);
|
|
@@ -224,11 +291,11 @@ class MeshGlBlitter {
|
|
|
224
291
|
return shader;
|
|
225
292
|
}
|
|
226
293
|
textureFor(page) {
|
|
227
|
-
let
|
|
228
|
-
if (texture)
|
|
229
|
-
return texture;
|
|
294
|
+
let entry = this.textures.get(page);
|
|
295
|
+
if (entry?.texture)
|
|
296
|
+
return entry.texture;
|
|
230
297
|
const gl = this.gl;
|
|
231
|
-
texture = gl.createTexture();
|
|
298
|
+
const texture = gl.createTexture();
|
|
232
299
|
if (!texture)
|
|
233
300
|
throw new Error('createTexture failed');
|
|
234
301
|
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
@@ -241,7 +308,17 @@ class MeshGlBlitter {
|
|
|
241
308
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
242
309
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
243
310
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
244
|
-
|
|
311
|
+
if (!entry) {
|
|
312
|
+
// Nobody retained this page — not a path this package takes, since the
|
|
313
|
+
// renderer retains as it queues each job. Cache it anyway so the batch
|
|
314
|
+
// does not re-upload per flush; with no users only a context loss (or
|
|
315
|
+
// the image being collected, which takes the weak entry with it) clears
|
|
316
|
+
// it, which is exactly the old behavior for a caller that opts out.
|
|
317
|
+
entry = { texture: null, users: 0 };
|
|
318
|
+
this.textures.set(page, entry);
|
|
319
|
+
}
|
|
320
|
+
entry.texture = texture;
|
|
321
|
+
this.liveTextureCount++;
|
|
245
322
|
return texture;
|
|
246
323
|
}
|
|
247
324
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MeshGlBlitter.js","sourceRoot":"","sources":["../src/MeshGlBlitter.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MeshGlBlitter.js","sourceRoot":"","sources":["../src/MeshGlBlitter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Skeleton } from '@esotericsoftware/spine-core';
|
|
2
|
-
import type { RegionImage } from './DomTexture';
|
|
2
|
+
import type { RegionImage } from './DomTexture.js';
|
|
3
3
|
/** Rasterizer used for the mesh (deform) tier. */
|
|
4
4
|
export type MeshBackend = 'canvas2d' | 'webgl';
|
|
5
5
|
/**
|
|
@@ -55,7 +55,8 @@ export declare class SpineHtmlRenderer {
|
|
|
55
55
|
* Mesh-canvas backing-store pixels per CSS pixel. Defaults to the device
|
|
56
56
|
* pixel ratio. If the caller scales the root element, fold that scale in
|
|
57
57
|
* (e.g. devicePixelRatio * rootScale) so the raster matches the on-screen
|
|
58
|
-
* resolution instead of over- or under-sampling
|
|
58
|
+
* resolution instead of over- or under-sampling — syncPixelRatio() measures
|
|
59
|
+
* that scale and folds it in for you.
|
|
59
60
|
*/
|
|
60
61
|
pixelRatio: number;
|
|
61
62
|
/**
|
|
@@ -78,6 +79,12 @@ export declare class SpineHtmlRenderer {
|
|
|
78
79
|
private readonly views;
|
|
79
80
|
private readonly pendingJobs;
|
|
80
81
|
private readonly pendingViews;
|
|
82
|
+
/**
|
|
83
|
+
* Atlas page images this renderer has retained from the shared blitter,
|
|
84
|
+
* one retain each. Allocated on the first webgl mesh job, so a renderer
|
|
85
|
+
* that never leaves canvas2d holds nothing and gives nothing back.
|
|
86
|
+
*/
|
|
87
|
+
private glPages;
|
|
81
88
|
private scratchVertices;
|
|
82
89
|
private tintDefs;
|
|
83
90
|
/**
|
|
@@ -87,23 +94,92 @@ export declare class SpineHtmlRenderer {
|
|
|
87
94
|
* @param regionImages Unpacked per-region bitmaps (for the rigid tier).
|
|
88
95
|
*/
|
|
89
96
|
constructor(root: HTMLElement, regionImages: Map<string, RegionImage>);
|
|
97
|
+
/**
|
|
98
|
+
* Backing-store pixels currently allocated across the mesh canvases
|
|
99
|
+
* (Σ width × height). Computed on demand from the views — nothing is
|
|
100
|
+
* tracked per frame — so reading it is cheap but not free; the demo reads it
|
|
101
|
+
* with the other counters, twice a second.
|
|
102
|
+
*
|
|
103
|
+
* This is the quantity `pixelRatio` moves quadratically, and the one that
|
|
104
|
+
* makes an oversampling stage visible before the frame rate does: a root
|
|
105
|
+
* scaled down by CSS without that scale folded into `pixelRatio` holds
|
|
106
|
+
* 1/scale² of the backing it needs. Hidden slots are included — their
|
|
107
|
+
* canvases keep their allocation.
|
|
108
|
+
*/
|
|
109
|
+
get meshBackingPixels(): number;
|
|
110
|
+
/**
|
|
111
|
+
* Re-derives `pixelRatio` from the root's effective on-screen scale, so the
|
|
112
|
+
* mesh tier rasters at the resolution the screen actually shows.
|
|
113
|
+
*
|
|
114
|
+
* Mesh canvases are sized in the root's own coordinates, and a CSS transform
|
|
115
|
+
* anywhere above the root — the natural way to build a pan/zoom stage is
|
|
116
|
+
* `transform: scale(zoom)` on an ancestor — rescales them on screen without
|
|
117
|
+
* the renderer seeing it. At zoom z the raster is then oversampled by 1/z per
|
|
118
|
+
* axis, 1/z² in backing pixels: GPU memory and fill rate, not correctness.
|
|
119
|
+
* This folds the measured scale in, `devicePixelRatio × scale`.
|
|
120
|
+
*
|
|
121
|
+
* One layout read per call. The root itself is usually 0×0 (slot elements are
|
|
122
|
+
* absolutely positioned and posed by transforms), so there is no box to
|
|
123
|
+
* measure: a hidden 100×100 px child is appended, measured once with
|
|
124
|
+
* getBoundingClientRect(), and removed again — nothing of it is left behind.
|
|
125
|
+
* It cannot disturb the slot elements either: they interleave by z-index,
|
|
126
|
+
* which applyCommon() writes explicitly on every visible one, so DOM order is
|
|
127
|
+
* not what orders them; and the probe is `visibility: hidden` and gone before
|
|
128
|
+
* anything can paint.
|
|
129
|
+
*
|
|
130
|
+
* The scale is the larger axis of the measured box. An ancestor rotation
|
|
131
|
+
* inflates that axis-aligned box, so the ratio errs high — the safe side:
|
|
132
|
+
* oversampling costs pixels, undersampling costs picture.
|
|
133
|
+
*
|
|
134
|
+
* A move smaller than 0.1% (see PIXEL_RATIO_DEADBAND) changes nothing, and a
|
|
135
|
+
* root that is not laid out (a `display: none` ancestor — the probe measures
|
|
136
|
+
* 0) changes nothing either. Both matter because writing `pixelRatio`
|
|
137
|
+
* reallocates every mesh canvas on the next frame.
|
|
138
|
+
*
|
|
139
|
+
* The renderer never calls this itself. It is a forced synchronous layout,
|
|
140
|
+
* which has no business in a render path — and there is no per-frame layout
|
|
141
|
+
* read anywhere in this class. Call it when a zoom or a layout settles: after
|
|
142
|
+
* a wheel/pinch gesture ends, on a debounced resize, not during the drag.
|
|
143
|
+
*
|
|
144
|
+
* @returns the pixel ratio now in effect (the current one if nothing moved).
|
|
145
|
+
*/
|
|
146
|
+
syncPixelRatio(): number;
|
|
90
147
|
render(skeleton: Skeleton): void;
|
|
91
148
|
/**
|
|
92
149
|
* Removes every element this renderer added to the root (slot elements and
|
|
93
|
-
* the tint filter defs)
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
150
|
+
* the tint filter defs), and hands the atlas pages it uploaded back to the
|
|
151
|
+
* shared GL blitter — the one resource here that outlives the instance, so
|
|
152
|
+
* the one that has to be given back explicitly (GPU memory, and no garbage
|
|
153
|
+
* collector feels pressure from it). The pages are reference-counted there:
|
|
154
|
+
* a page another live renderer still draws stays uploaded, and the texture
|
|
155
|
+
* is deleted only when the last user of it is disposed.
|
|
156
|
+
*
|
|
157
|
+
* The region bitmaps are deliberately untouched: the map is the caller's,
|
|
158
|
+
* and one map is normally shared by many renderers (disposing one instance
|
|
159
|
+
* must not blind the others). Free the unpacked blob URLs with
|
|
160
|
+
* revokeRegions() once no renderer needs them.
|
|
161
|
+
*
|
|
162
|
+
* Idempotent: the retained-page ledger is cleared here, so a second call
|
|
163
|
+
* releases nothing a second time.
|
|
97
164
|
*/
|
|
98
165
|
dispose(): void;
|
|
99
166
|
private renderRegion;
|
|
100
167
|
private renderMesh;
|
|
168
|
+
/**
|
|
169
|
+
* Declares this renderer a user of `page` with the shared blitter, once per
|
|
170
|
+
* page — the counterpart of the release in dispose(). The set is this
|
|
171
|
+
* renderer's own ledger, so sharing one page across renderers works by
|
|
172
|
+
* counting rather than by guessing. On the render path this costs one
|
|
173
|
+
* Set.has per queued mesh job and allocates nothing after the first page.
|
|
174
|
+
*/
|
|
175
|
+
private retainPage;
|
|
101
176
|
/** The canvas2d raster path: clear the backing, map each triangle. */
|
|
102
177
|
private rasterizeMesh2d;
|
|
103
178
|
/**
|
|
104
179
|
* Standard canvas triangle texture mapping (same math as the official
|
|
105
180
|
* spine-canvas renderer): derive the affine that sends the triangle's
|
|
106
|
-
* texture-space corners to its screen-space corners, clip, draw the page
|
|
181
|
+
* texture-space corners to its screen-space corners, clip, draw the page —
|
|
182
|
+
* but only the part of the page this triangle can show (see below).
|
|
107
183
|
*
|
|
108
184
|
* The clip polygon is expanded outward from the centroid by a fraction of
|
|
109
185
|
* a pixel. Browsers that antialias clip paths (Safari) otherwise leave
|
|
@@ -112,6 +188,44 @@ export declare class SpineHtmlRenderer {
|
|
|
112
188
|
* across the shared edge the overlap draws the same pixels — cracks close
|
|
113
189
|
* with no visible cost. The texture-mapping affine itself stays exact.
|
|
114
190
|
*
|
|
191
|
+
* ## Why a source sub-rect instead of the whole page
|
|
192
|
+
*
|
|
193
|
+
* The draw is a 9-argument `drawImage` whose source rect covers exactly what
|
|
194
|
+
* the clip can reveal, placed at the same texture-space position, so the
|
|
195
|
+
* mapping is identical to drawing the whole page — the same affine, the same
|
|
196
|
+
* texels, only fewer of them offered to the rasterizer.
|
|
197
|
+
*
|
|
198
|
+
* That is not an optimization. Linux WebKit — the software rasterizer, the
|
|
199
|
+
* only engine this has been observed on; Chromium and macOS WebKit never show
|
|
200
|
+
* it — garbles individual triangles when the whole page is drawn under a
|
|
201
|
+
* steep per-triangle affine: read off the parity dump, head/goggles/foot
|
|
202
|
+
* triangles land with displaced texture while the webgl capture of the same
|
|
203
|
+
* pose stays clean. Switching this one call to a source sub-rect — the only
|
|
204
|
+
* variable changed — took that platform's bad-pixel counts from 1042 to 2
|
|
205
|
+
* (hoverboard), 231 to 4 (portal) and 803 to 3 (walk + tint), and left every
|
|
206
|
+
* Chromium capture byte-identical. [measured on the ubuntu CI runner through
|
|
207
|
+
* PARITY_DUMP: first with a fixed 2-texel pad (run 35209262693), then with
|
|
208
|
+
* the derived rect below — the same counts (run 35213286993).] WHY that
|
|
209
|
+
* rasterizer garbles the whole-page form is not identified; steep affines
|
|
210
|
+
* making whole-page coordinates large is a suspicion, not a measurement. The
|
|
211
|
+
* sub-rect sidesteps it. (Moving `clip()` before `transform()` was tried as a
|
|
212
|
+
* separate one-variable experiment: every number came back identical, so the
|
|
213
|
+
* clip path is not the cause.)
|
|
214
|
+
*
|
|
215
|
+
* ## How the sub-rect is derived
|
|
216
|
+
*
|
|
217
|
+
* It must provably cover everything the clip can reveal, which is the
|
|
218
|
+
* *expanded* polygon, not the triangle. So each clip corner's canvas-space
|
|
219
|
+
* displacement is pushed back through the inverse of the 2×2 affine into
|
|
220
|
+
* texture space, the bounding box is taken over the displaced corners, one
|
|
221
|
+
* texel of bilinear support is added, and the result is floor/ceil'd to texel
|
|
222
|
+
* boundaries (so the sub-rect itself resamples nothing) and clamped to the
|
|
223
|
+
* page. A fixed pad would not do: the texture-space reach of the expansion is
|
|
224
|
+
* `triangleExpand` times the local texels-per-canvas-unit, which on the
|
|
225
|
+
* demo's own meshes ranges from ~0.26 texels on a typical triangle to ~8.6 on
|
|
226
|
+
* a foreshortened one. Under-padding lets the rim of the overdraw sample
|
|
227
|
+
* nothing, which brings back the very seams the overdraw exists to close.
|
|
228
|
+
*
|
|
115
229
|
* No half-texel offset is applied to the incoming u/v: the `(i + 0.5) / size`
|
|
116
230
|
* texel-centre convention belongs to *sampling* (landing inside the intended
|
|
117
231
|
* texel instead of on a filter boundary). This solves for the affine that
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpineHtmlRenderer.d.ts","sourceRoot":"","sources":["../src/SpineHtmlRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,QAAQ,EAId,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"SpineHtmlRenderer.d.ts","sourceRoot":"","sources":["../src/SpineHtmlRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,QAAQ,EAId,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD,kDAAkD;AAClD,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;AA4E/C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,iBAAiB;IAkE1B,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAlE/B,kEAAkE;IAClE,aAAa,SAAK;IAClB,2CAA2C;IAC3C,SAAS,SAAK;IACd,kEAAkE;IAClE,cAAc,SAAK;IACnB;;;;OAIG;IACH,kBAAkB,SAAK;IACvB,uCAAuC;IACvC,aAAa,SAAK;IAClB;;;;OAIG;IACH,cAAc,SAAO;IACrB;;;;;;OAMG;IACH,UAAU,SAA+D;IACzE;;;;;;;;;;;;;OAaG;IACH,WAAW,EAAE,WAAW,CAAc;IACtC,+EAA+E;IAC/E,iBAAiB,EAAE,WAAW,CAAc;IAE5C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IACnD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkB;IAC/C;;;;OAIG;IACH,OAAO,CAAC,OAAO,CAAsC;IACrD,OAAO,CAAC,eAAe,CAAyB;IAChD,OAAO,CAAC,QAAQ,CAA8B;IAE9C;;;;;OAKG;gBAEgB,IAAI,EAAE,WAAW,EACjB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC;IAGzD;;;;;;;;;;;OAWG;IACH,IAAI,iBAAiB,IAAI,MAAM,CAM9B;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACH,cAAc,IAAI,MAAM;IAiCxB,MAAM,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IA4ChC;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,IAAI,IAAI;IAcf,OAAO,CAAC,YAAY;IA8CpB,OAAO,CAAC,UAAU;IA+IlB;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAWlB,sEAAsE;IACtE,OAAO,CAAC,eAAe;IAqCvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA0DG;IACH,OAAO,CAAC,YAAY;IA8EpB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,WAAW;IAmDnB,OAAO,CAAC,aAAa;IAyBrB,OAAO,CAAC,IAAI;IA+CZ,OAAO,CAAC,IAAI;CAOb"}
|