@flighthq/scene2d-gl 0.2.1-next.840.857425c

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.
Files changed (138) hide show
  1. package/dist/enableGlColorAdjustmentGuards.d.ts +4 -0
  2. package/dist/enableGlColorAdjustmentGuards.d.ts.map +1 -0
  3. package/dist/enableGlColorAdjustmentGuards.js +21 -0
  4. package/dist/enableGlColorAdjustmentGuards.js.map +1 -0
  5. package/dist/glBitmap.d.ts +4 -0
  6. package/dist/glBitmap.d.ts.map +1 -0
  7. package/dist/glBitmap.js +93 -0
  8. package/dist/glBitmap.js.map +1 -0
  9. package/dist/glCache.d.ts +30 -0
  10. package/dist/glCache.d.ts.map +1 -0
  11. package/dist/glCache.js +196 -0
  12. package/dist/glCache.js.map +1 -0
  13. package/dist/glClip.d.ts +3 -0
  14. package/dist/glClip.d.ts.map +1 -0
  15. package/dist/glClip.js +46 -0
  16. package/dist/glClip.js.map +1 -0
  17. package/dist/glClipContours.d.ts +4 -0
  18. package/dist/glClipContours.d.ts.map +1 -0
  19. package/dist/glClipContours.js +148 -0
  20. package/dist/glClipContours.js.map +1 -0
  21. package/dist/glClipRectangle.d.ts +4 -0
  22. package/dist/glClipRectangle.d.ts.map +1 -0
  23. package/dist/glClipRectangle.js +68 -0
  24. package/dist/glClipRectangle.js.map +1 -0
  25. package/dist/glColorAdjustment.d.ts +3 -0
  26. package/dist/glColorAdjustment.d.ts.map +1 -0
  27. package/dist/glColorAdjustment.js +361 -0
  28. package/dist/glColorAdjustment.js.map +1 -0
  29. package/dist/glDefaultMaterial.d.ts +4 -0
  30. package/dist/glDefaultMaterial.d.ts.map +1 -0
  31. package/dist/glDefaultMaterial.js +20 -0
  32. package/dist/glDefaultMaterial.js.map +1 -0
  33. package/dist/glNode2D.d.ts +5 -0
  34. package/dist/glNode2D.d.ts.map +1 -0
  35. package/dist/glNode2D.js +41 -0
  36. package/dist/glNode2D.js.map +1 -0
  37. package/dist/glNode2DRegistration.d.ts +25 -0
  38. package/dist/glNode2DRegistration.d.ts.map +1 -0
  39. package/dist/glNode2DRegistration.js +51 -0
  40. package/dist/glNode2DRegistration.js.map +1 -0
  41. package/dist/glParticleEmitter2D.d.ts +4 -0
  42. package/dist/glParticleEmitter2D.d.ts.map +1 -0
  43. package/dist/glParticleEmitter2D.js +263 -0
  44. package/dist/glParticleEmitter2D.js.map +1 -0
  45. package/dist/glQuadBatch.d.ts +3 -0
  46. package/dist/glQuadBatch.d.ts.map +1 -0
  47. package/dist/glQuadBatch.js +92 -0
  48. package/dist/glQuadBatch.js.map +1 -0
  49. package/dist/glRichText.d.ts +8 -0
  50. package/dist/glRichText.d.ts.map +1 -0
  51. package/dist/glRichText.js +161 -0
  52. package/dist/glRichText.js.map +1 -0
  53. package/dist/glScale9Mapper.d.ts +3 -0
  54. package/dist/glScale9Mapper.d.ts.map +1 -0
  55. package/dist/glScale9Mapper.js +37 -0
  56. package/dist/glScale9Mapper.js.map +1 -0
  57. package/dist/glScale9Shape.d.ts +9 -0
  58. package/dist/glScale9Shape.d.ts.map +1 -0
  59. package/dist/glScale9Shape.js +118 -0
  60. package/dist/glScale9Shape.js.map +1 -0
  61. package/dist/glShape.d.ts +4 -0
  62. package/dist/glShape.d.ts.map +1 -0
  63. package/dist/glShape.js +146 -0
  64. package/dist/glShape.js.map +1 -0
  65. package/dist/glShapeMesh.d.ts +5 -0
  66. package/dist/glShapeMesh.d.ts.map +1 -0
  67. package/dist/glShapeMesh.js +114 -0
  68. package/dist/glShapeMesh.js.map +1 -0
  69. package/dist/glSprite.d.ts +3 -0
  70. package/dist/glSprite.d.ts.map +1 -0
  71. package/dist/glSprite.js +28 -0
  72. package/dist/glSprite.js.map +1 -0
  73. package/dist/glSpriteBatch.d.ts +11 -0
  74. package/dist/glSpriteBatch.d.ts.map +1 -0
  75. package/dist/glSpriteBatch.js +277 -0
  76. package/dist/glSpriteBatch.js.map +1 -0
  77. package/dist/glSpriteRenderer.d.ts +3 -0
  78. package/dist/glSpriteRenderer.d.ts.map +1 -0
  79. package/dist/glSpriteRenderer.js +54 -0
  80. package/dist/glSpriteRenderer.js.map +1 -0
  81. package/dist/glTestHelper.d.ts +9 -0
  82. package/dist/glTestHelper.d.ts.map +1 -0
  83. package/dist/glTestHelper.js +17 -0
  84. package/dist/glTestHelper.js.map +1 -0
  85. package/dist/glTextInput.d.ts +4 -0
  86. package/dist/glTextInput.d.ts.map +1 -0
  87. package/dist/glTextInput.js +43 -0
  88. package/dist/glTextInput.js.map +1 -0
  89. package/dist/glTextLabel.d.ts +4 -0
  90. package/dist/glTextLabel.d.ts.map +1 -0
  91. package/dist/glTextLabel.js +141 -0
  92. package/dist/glTextLabel.js.map +1 -0
  93. package/dist/glTilemap.d.ts +3 -0
  94. package/dist/glTilemap.d.ts.map +1 -0
  95. package/dist/glTilemap.js +79 -0
  96. package/dist/glTilemap.js.map +1 -0
  97. package/dist/glVelocity.d.ts +22 -0
  98. package/dist/glVelocity.d.ts.map +1 -0
  99. package/dist/glVelocity.js +319 -0
  100. package/dist/glVelocity.js.map +1 -0
  101. package/dist/glVideo.d.ts +6 -0
  102. package/dist/glVideo.d.ts.map +1 -0
  103. package/dist/glVideo.js +62 -0
  104. package/dist/glVideo.js.map +1 -0
  105. package/dist/index.d.ts +27 -0
  106. package/dist/index.d.ts.map +1 -0
  107. package/dist/index.js +28 -0
  108. package/dist/index.js.map +1 -0
  109. package/dist/moduleMockTestHelper.d.ts +15 -0
  110. package/dist/moduleMockTestHelper.d.ts.map +1 -0
  111. package/dist/moduleMockTestHelper.js +25 -0
  112. package/dist/moduleMockTestHelper.js.map +1 -0
  113. package/package.json +60 -0
  114. package/src/enableGlColorAdjustmentGuards.test.ts +76 -0
  115. package/src/glBitmap.test.ts +136 -0
  116. package/src/glCache.test.ts +234 -0
  117. package/src/glClip.test.ts +101 -0
  118. package/src/glClipContours.test.ts +61 -0
  119. package/src/glClipRectangle.test.ts +47 -0
  120. package/src/glColorAdjustment.test.ts +166 -0
  121. package/src/glDefaultMaterial.test.ts +19 -0
  122. package/src/glNode2D.test.ts +85 -0
  123. package/src/glNode2DRegistration.test.ts +132 -0
  124. package/src/glParticleEmitter2D.test.ts +122 -0
  125. package/src/glQuadBatch.test.ts +132 -0
  126. package/src/glRichText.test.ts +140 -0
  127. package/src/glScale9Mapper.test.ts +20 -0
  128. package/src/glScale9Shape.test.ts +90 -0
  129. package/src/glShape.test.ts +116 -0
  130. package/src/glShapeMesh.test.ts +164 -0
  131. package/src/glSprite.test.ts +79 -0
  132. package/src/glSpriteBatch.test.ts +249 -0
  133. package/src/glSpriteRenderer.test.ts +89 -0
  134. package/src/glTextInput.test.ts +51 -0
  135. package/src/glTextLabel.test.ts +156 -0
  136. package/src/glTilemap.test.ts +127 -0
  137. package/src/glVelocity.test.ts +156 -0
  138. package/src/glVideo.test.ts +98 -0
@@ -0,0 +1,4 @@
1
+ import type { GlRenderState } from '@flighthq/types';
2
+ export declare function areGlColorAdjustmentGuardsEnabled(state: GlRenderState): boolean;
3
+ export declare function enableGlColorAdjustmentGuards(state: GlRenderState): void;
4
+ //# sourceMappingURL=enableGlColorAdjustmentGuards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enableGlColorAdjustmentGuards.d.ts","sourceRoot":"","sources":["../src/enableGlColorAdjustmentGuards.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIrD,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAE/E;AAOD,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAExE"}
@@ -0,0 +1,21 @@
1
+ import { logOnce } from '@flighthq/log';
2
+ import { getGlRenderStateRuntime } from '@flighthq/render-gl';
3
+ import { LogLevel } from '@flighthq/types';
4
+ // Returns whether color-adjustment guards are installed on `state` (enableGlColorAdjustmentGuards).
5
+ export function areGlColorAdjustmentGuardsEnabled(state) {
6
+ return getGlRenderStateRuntime(state).glColorAdjustmentGuard != null;
7
+ }
8
+ // Installs the shakeable color-adjustment guard on `state`: when a node carries a color transform but
9
+ // enableGlColorAdjustment was never called, recordGlSpriteBatchColorTransform reaches this guard
10
+ // through its nullable runtime slot and warns once (the tint is skipped, drawn untinted — the sentinel
11
+ // behavior, never a throw). Not calling this — the production default — costs the batch nothing, since
12
+ // the message and @flighthq/log dependency live only in this separately-imported module. Idempotent.
13
+ export function enableGlColorAdjustmentGuards(state) {
14
+ getGlRenderStateRuntime(state).glColorAdjustmentGuard = warnGlColorAdjustmentNotEnabled;
15
+ }
16
+ function warnGlColorAdjustmentNotEnabled() {
17
+ logOnce('scene2d-gl:color-adjustment-not-enabled', LogLevel.Warn, {
18
+ message: 'recordGlSpriteBatchColorTransform: color transform present but GL color adjustment not enabled — call enableGlColorAdjustment(state)',
19
+ }, 'scene2d-gl');
20
+ }
21
+ //# sourceMappingURL=enableGlColorAdjustmentGuards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enableGlColorAdjustmentGuards.js","sourceRoot":"","sources":["../src/enableGlColorAdjustmentGuards.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,oGAAoG;AACpG,MAAM,UAAU,iCAAiC,CAAC,KAAoB;IACpE,OAAO,uBAAuB,CAAC,KAAK,CAAC,CAAC,sBAAsB,IAAI,IAAI,CAAC;AACvE,CAAC;AAED,sGAAsG;AACtG,iGAAiG;AACjG,uGAAuG;AACvG,uGAAuG;AACvG,qGAAqG;AACrG,MAAM,UAAU,6BAA6B,CAAC,KAAoB;IAChE,uBAAuB,CAAC,KAAK,CAAC,CAAC,sBAAsB,GAAG,+BAA+B,CAAC;AAC1F,CAAC;AAED,SAAS,+BAA+B;IACtC,OAAO,CACL,yCAAyC,EACzC,QAAQ,CAAC,IAAI,EACb;QACE,OAAO,EACL,sIAAsI;KACzI,EACD,YAAY,CACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Scene2DRenderer, GlRenderState, RenderProxy2D } from '@flighthq/types';
2
+ export declare function drawGlBitmap(state: GlRenderState, renderProxy: RenderProxy2D): void;
3
+ export declare const defaultGlBitmapRenderer: Scene2DRenderer;
4
+ //# sourceMappingURL=glBitmap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glBitmap.d.ts","sourceRoot":"","sources":["../src/glBitmap.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEV,eAAe,EACf,aAAa,EAIb,aAAa,EACd,MAAM,iBAAiB,CAAC;AAgCzB,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,GAAG,IAAI,CAwEnF;AAED,eAAO,MAAM,uBAAuB,EAAE,eAKrC,CAAC"}
@@ -0,0 +1,93 @@
1
+ import { hasImageResourcePixels } from '@flighthq/image';
2
+ import { resolveGlMaterialRenderer } from '@flighthq/render-gl';
3
+ import { getGlRenderStateRuntime } from '@flighthq/render-gl';
4
+ import { BatchFormat } from '@flighthq/types';
5
+ import { ensureGlQuadBatchShader, packGlSpriteBatchMaterialInstance, prepareGlSpriteBatchWrite, recordGlSpriteBatchColorTransform, } from './glSpriteBatch';
6
+ function createGlBitmapData(_state, _source) {
7
+ return { image: null };
8
+ }
9
+ // Deletes the cached GPU texture when this bitmap is torn down. Prevents textures from leaking when
10
+ // a bitmap is removed from the scene via disposeScene2DRender. Content-change re-upload is handled
11
+ // by bindGlTexture's version-aware cache, so this only frees on teardown.
12
+ function destroyGlBitmapData(state, data) {
13
+ const runtime = getGlRenderStateRuntime(state);
14
+ const { image } = data;
15
+ if (image === null)
16
+ return;
17
+ const entry = runtime.imageResourceTextureCache.get(image);
18
+ if (entry !== undefined) {
19
+ state.gl.deleteTexture(entry.texture);
20
+ runtime.imageResourceTextureCache.delete(image);
21
+ }
22
+ }
23
+ export function drawGlBitmap(state, renderProxy) {
24
+ const runtime = getGlRenderStateRuntime(state);
25
+ const source = renderProxy.source;
26
+ const imageSource = source.data.image;
27
+ if (imageSource === null || !hasImageResourcePixels(imageSource))
28
+ return;
29
+ if (renderProxy.rendererData === null)
30
+ return;
31
+ // Recorded so teardown can free the resource's cached GPU texture; re-upload on content change is the
32
+ // cache's job (keyed by the resource, version-aware), not this node's.
33
+ renderProxy.rendererData.image = imageSource;
34
+ const material = renderProxy.material;
35
+ const materialRenderer = resolveGlMaterialRenderer(state, material);
36
+ if (materialRenderer === null)
37
+ return;
38
+ ensureGlQuadBatchShader(state);
39
+ const sr = source.data.sourceRectangle ?? null;
40
+ const iw = 1 / (imageSource.width || 1);
41
+ const ih = 1 / (imageSource.height || 1);
42
+ let w;
43
+ let h;
44
+ let u0;
45
+ let v0;
46
+ let u1;
47
+ let v1;
48
+ if (sr === null) {
49
+ w = imageSource.width;
50
+ h = imageSource.height;
51
+ u0 = 0;
52
+ v0 = 0;
53
+ u1 = 1;
54
+ v1 = 1;
55
+ }
56
+ else {
57
+ w = sr.width;
58
+ h = sr.height;
59
+ u0 = sr.x * iw;
60
+ v0 = sr.y * ih;
61
+ u1 = (sr.x + sr.width) * iw;
62
+ v1 = (sr.y + sr.height) * ih;
63
+ }
64
+ const startCount = runtime.spriteBatchCount;
65
+ // Per-bitmap smoothing keys the batch so a NEAREST bitmap never inherits a LINEAR neighbor's filter
66
+ // (and vice versa); the flush binds the texture with this filter instead of the global default.
67
+ const base = prepareGlSpriteBatchWrite(state, imageSource, renderProxy.blendMode, material, materialRenderer, 1, source.data.smoothing);
68
+ const d = runtime.spriteBatchInstanceData;
69
+ const t = renderProxy.transform2D;
70
+ d[base] = t.a;
71
+ d[base + 1] = t.b;
72
+ d[base + 2] = t.c;
73
+ d[base + 3] = t.d;
74
+ d[base + 4] = t.tx;
75
+ d[base + 5] = t.ty;
76
+ d[base + 6] = w;
77
+ d[base + 7] = h;
78
+ d[base + 8] = u0;
79
+ d[base + 9] = v0;
80
+ d[base + 10] = u1;
81
+ d[base + 11] = v1;
82
+ d[base + 12] = renderProxy.alpha;
83
+ packGlSpriteBatchMaterialInstance(state, renderProxy.materialData, startCount);
84
+ recordGlSpriteBatchColorTransform(state, renderProxy.colorTransform, startCount);
85
+ runtime.spriteBatchCount++;
86
+ }
87
+ export const defaultGlBitmapRenderer = {
88
+ format: BatchFormat.Quad,
89
+ createData: createGlBitmapData,
90
+ destroyData: destroyGlBitmapData,
91
+ submit: drawGlBitmap,
92
+ };
93
+ //# sourceMappingURL=glBitmap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glBitmap.js","sourceRoot":"","sources":["../src/glBitmap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { Node2D, Scene2DRenderer, GlRenderState, GlRenderTarget, RenderCache, RenderCacheRefreshOptions } from '@flighthq/types';
2
+ /**
3
+ * Creates an offscreen render state for baking render caches consumed by `screenState`.
4
+ *
5
+ * Gl textures and framebuffers cannot cross GL contexts, so — unlike the canvas backend —
6
+ * this offscreen state must share the screen state's GL context and every context-bound
7
+ * resource (shaders, buffers, the uploaded-texture cache). What it keeps separate is the
8
+ * scene-graph bookkeeping: its own render node map, adapter map, and frame counter, so baking
9
+ * neither substitutes a cache into itself nor disturbs the screen state's nodes.
10
+ */
11
+ export declare function createGlCacheState(screenState: GlRenderState): GlRenderState;
12
+ export declare function enableGlRenderCache(state: GlRenderState): void;
13
+ /**
14
+ * Allocates or resizes the framebuffer-backed texture `screenState` composites for `cache`,
15
+ * returning it so a caller can render custom content into it directly. For engine-baked
16
+ * content prefer refreshGlRenderCache.
17
+ */
18
+ export declare function ensureGlRenderCacheTarget(state: GlRenderState, cache: RenderCache, width: number, height: number): GlRenderTarget;
19
+ export declare function getGlRenderCacheTarget(state: GlRenderState, cache: RenderCache): GlRenderTarget | null;
20
+ /**
21
+ * Bakes `source`'s subtree into its cache target using the offscreen `cacheState`, then records
22
+ * the transform that places the result back in scene space. Returns whether a bake happened —
23
+ * the offscreen state's own dirtiness decides it (honoring its sceneGraphSyncPolicy), so this is
24
+ * cheap to call every frame. Because the bake runs on the shared GL context, the screen state's
25
+ * cached GL state is reset afterward so it re-establishes cleanly on its next draw.
26
+ */
27
+ export declare function refreshGlRenderCache(cacheState: GlRenderState, cache: RenderCache, source: Node2D, options?: Readonly<RenderCacheRefreshOptions>): boolean;
28
+ export declare function releaseGlRenderCache(state: GlRenderState, cache: RenderCache): void;
29
+ export declare const defaultGlRenderCacheRenderer: Scene2DRenderer;
30
+ //# sourceMappingURL=glCache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glCache.d.ts","sourceRoot":"","sources":["../src/glCache.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EACV,MAAM,EACN,eAAe,EACf,aAAa,EACb,cAAc,EAEd,WAAW,EACX,yBAAyB,EAE1B,MAAM,iBAAiB,CAAC;AAMzB;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,aAAa,GAAG,aAAa,CAiE5E;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,cAAc,CAUhB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,GAAG,cAAc,GAAG,IAAI,CAEtG;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,aAAa,EACzB,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,QAAQ,CAAC,yBAAyB,CAAC,GAC5C,OAAO,CA8CT;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAOnF;AA0BD,eAAO,MAAM,4BAA4B,EAAE,eAG1C,CAAC"}
@@ -0,0 +1,196 @@
1
+ import { createMatrix, createRectangle } from '@flighthq/geometry';
2
+ import { computeNodeBoundsRectangle } from '@flighthq/node';
3
+ import { computeScene2DRenderTargetTransform, computeRenderCacheTransform, computeRenderTargetSize, copyAllRenderersFromRenderState, createRenderState, getRenderProxyCache, noopRendererData, prepareScene2DRender, registerRenderCacheRenderer, } from '@flighthq/render';
4
+ import { createGlRenderStateRuntime, getGlRenderStateRuntime } from '@flighthq/render-gl';
5
+ import { beginGlRenderPass, createGlRenderTarget, destroyGlRenderTarget, drawGlRenderTargetResult, endGlRenderPass, resizeGlRenderTarget, setGlRenderTransform2D, } from '@flighthq/render-gl';
6
+ import { EntityRuntimeKey } from '@flighthq/types';
7
+ import { renderGlScene2D } from './glNode2D';
8
+ import { flushGlSpriteBatch } from './glSpriteBatch';
9
+ /**
10
+ * Creates an offscreen render state for baking render caches consumed by `screenState`.
11
+ *
12
+ * Gl textures and framebuffers cannot cross GL contexts, so — unlike the canvas backend —
13
+ * this offscreen state must share the screen state's GL context and every context-bound
14
+ * resource (shaders, buffers, the uploaded-texture cache). What it keeps separate is the
15
+ * scene-graph bookkeeping: its own render node map, adapter map, and frame counter, so baking
16
+ * neither substitutes a cache into itself nor disturbs the screen state's nodes.
17
+ */
18
+ export function createGlCacheState(screenState) {
19
+ const screenRuntime = getGlRenderStateRuntime(screenState);
20
+ const cacheState = createRenderState({
21
+ allowSmoothing: screenState.allowSmoothing,
22
+ pixelRatio: screenState.pixelRatio,
23
+ renderTransform2D: createMatrix(),
24
+ roundPixels: screenState.roundPixels,
25
+ sceneGraphSyncPolicy: screenState.sceneGraphSyncPolicy,
26
+ });
27
+ // Attach the cache runtime before copying renderers: copyAllRenderersFromRenderState registers
28
+ // into the runtime's rendererMap, so the backend runtime must already be installed.
29
+ const cacheRuntime = createGlRenderStateRuntime();
30
+ cacheState[EntityRuntimeKey] = cacheRuntime;
31
+ copyAllRenderersFromRenderState(cacheState, screenState);
32
+ cacheState.applyBlendMode = screenState.applyBlendMode;
33
+ cacheState.canvas = screenState.canvas;
34
+ cacheState.gl = screenState.gl;
35
+ cacheRuntime.defaultBitmapShader = screenRuntime.defaultBitmapShader;
36
+ cacheRuntime.particleShader = screenRuntime.particleShader;
37
+ cacheRuntime.particleCornerBuffer = screenRuntime.particleCornerBuffer;
38
+ cacheRuntime.particleInstanceBuffer = screenRuntime.particleInstanceBuffer;
39
+ cacheRuntime.particleInstanceData = screenRuntime.particleInstanceData;
40
+ cacheRuntime.quadBatchShader = screenRuntime.quadBatchShader;
41
+ cacheRuntime.quadBatchCornerBuffer = screenRuntime.quadBatchCornerBuffer;
42
+ cacheRuntime.colorTransformInstancedShader = screenRuntime.colorTransformInstancedShader;
43
+ cacheRuntime.uniformColorTransformShader = screenRuntime.uniformColorTransformShader;
44
+ // Propagate the opt-in color-adjustment fold + guard so tinted nodes inside a cached subtree fold
45
+ // the same way when baked offscreen. Their per-batch CT data lives on cacheRuntime, lazily grown.
46
+ cacheRuntime.glColorAdjustmentFold = screenRuntime.glColorAdjustmentFold;
47
+ cacheRuntime.glColorAdjustmentGuard = screenRuntime.glColorAdjustmentGuard;
48
+ cacheRuntime.materialRendererMap = screenRuntime.materialRendererMap;
49
+ cacheRuntime.materialBitmapShaderMap = screenRuntime.materialBitmapShaderMap;
50
+ cacheRuntime.shaderLoc = screenRuntime.shaderLoc;
51
+ cacheRuntime.textureCache = screenRuntime.textureCache;
52
+ cacheRuntime.quadVertexBuffer = screenRuntime.quadVertexBuffer;
53
+ cacheRuntime.quadIndexBuffer = screenRuntime.quadIndexBuffer;
54
+ cacheRuntime.quadVertexData = screenRuntime.quadVertexData;
55
+ cacheRuntime.matrixArray = screenRuntime.matrixArray;
56
+ cacheRuntime.currentBlendMode = null;
57
+ cacheRuntime.currentFramebuffer = null;
58
+ cacheRuntime.currentMaskDepth = 0;
59
+ cacheRuntime.currentProgram = null;
60
+ cacheRuntime.currentScissorRect = null;
61
+ cacheRuntime.currentTexture = null;
62
+ cacheRuntime.currentTextureStraightAlpha = false;
63
+ cacheRuntime.renderTargetViewport = null;
64
+ cacheRuntime.scissorStack = [];
65
+ cacheRuntime.spriteBatchBlendMode = null;
66
+ cacheRuntime.spriteBatchMaterial = null;
67
+ cacheRuntime.spriteBatchMaterialRenderer = null;
68
+ cacheRuntime.spriteBatchMaterialFloats = 0;
69
+ cacheRuntime.spriteBatchMaterialData = new Float32Array(0);
70
+ cacheRuntime.spriteBatchMaterialBuffer = null;
71
+ cacheRuntime.spriteBatchCount = 0;
72
+ cacheRuntime.spriteBatchInstanceBuffer = null;
73
+ cacheRuntime.spriteBatchInstanceData = new Float32Array(0);
74
+ cacheRuntime.spriteBatchTexture = null;
75
+ cacheRuntime.spriteBatchSmoothing = null;
76
+ _cacheStateScreen.set(cacheState, screenState);
77
+ return cacheState;
78
+ }
79
+ export function enableGlRenderCache(state) {
80
+ registerRenderCacheRenderer(state, defaultGlRenderCacheRenderer);
81
+ }
82
+ /**
83
+ * Allocates or resizes the framebuffer-backed texture `screenState` composites for `cache`,
84
+ * returning it so a caller can render custom content into it directly. For engine-baked
85
+ * content prefer refreshGlRenderCache.
86
+ */
87
+ export function ensureGlRenderCacheTarget(state, cache, width, height) {
88
+ const targets = getTargets(state);
89
+ let target = targets.get(cache);
90
+ if (target === undefined) {
91
+ target = createGlRenderTarget(state, { width, height });
92
+ targets.set(cache, target);
93
+ }
94
+ else {
95
+ resizeGlRenderTarget(state, target, width, height);
96
+ }
97
+ return target;
98
+ }
99
+ export function getGlRenderCacheTarget(state, cache) {
100
+ return getTargets(state).get(cache) ?? null;
101
+ }
102
+ /**
103
+ * Bakes `source`'s subtree into its cache target using the offscreen `cacheState`, then records
104
+ * the transform that places the result back in scene space. Returns whether a bake happened —
105
+ * the offscreen state's own dirtiness decides it (honoring its sceneGraphSyncPolicy), so this is
106
+ * cheap to call every frame. Because the bake runs on the shared GL context, the screen state's
107
+ * cached GL state is reset afterward so it re-establishes cleanly on its next draw.
108
+ */
109
+ export function refreshGlRenderCache(cacheState, cache, source, options) {
110
+ const screenState = _cacheStateScreen.get(cacheState) ?? cacheState;
111
+ const padding = options?.padding ?? 0;
112
+ const minWidth = options?.minWidth ?? 1;
113
+ const minHeight = options?.minHeight ?? 1;
114
+ computeNodeBoundsRectangle(_bounds, source, source);
115
+ const { width, height } = computeRenderTargetSize(_bounds, padding, minWidth, minHeight);
116
+ const existing = getGlRenderCacheTarget(screenState, cache);
117
+ const resized = existing === null || existing.width !== width || existing.height !== height;
118
+ const target = ensureGlRenderCacheTarget(screenState, cache, width, height);
119
+ computeScene2DRenderTargetTransform(_renderTransform, source, _bounds, padding, padding);
120
+ computeRenderCacheTransform(cache.transform, _bounds, padding, padding);
121
+ // Preserve on begin — the bake below clears and redraws only when dirty; clearing here would wipe the
122
+ // retained cache content on the not-dirty path. The cache's local-space transform is set explicitly,
123
+ // since a pass no longer carries one.
124
+ beginGlRenderPass(cacheState, target, { preserveColor: true, preserveDepth: true });
125
+ setGlRenderTransform2D(cacheState, _renderTransform);
126
+ const dirty = prepareScene2DRender(cacheState, source);
127
+ if (dirty || resized) {
128
+ const cacheRuntime = getGlRenderStateRuntime(cacheState);
129
+ // The cache state shares the screen's GL context, so the actual GL program/blend/scissor are
130
+ // whatever the screen render (or a prior blur pass) last left — state this cache state does not
131
+ // track. Reset its cached GL state so the bake re-establishes everything instead of skipping a
132
+ // rebind and setting uniforms on the wrong program.
133
+ cacheRuntime.currentProgram = null;
134
+ cacheRuntime.currentTexture = null;
135
+ cacheRuntime.currentTextureStraightAlpha = false;
136
+ cacheRuntime.currentBlendMode = null;
137
+ cacheRuntime.currentScissorRect = null;
138
+ cacheState.gl.clearColor(0, 0, 0, 0);
139
+ cacheState.gl.clear(cacheState.gl.COLOR_BUFFER_BIT);
140
+ renderGlScene2D(cacheState, source);
141
+ }
142
+ endGlRenderPass(cacheState);
143
+ const screenRuntime = getGlRenderStateRuntime(screenState);
144
+ screenRuntime.currentBlendMode = null;
145
+ screenRuntime.currentProgram = null;
146
+ screenRuntime.currentScissorRect = null;
147
+ screenRuntime.currentTexture = null;
148
+ screenRuntime.currentTextureStraightAlpha = false;
149
+ return dirty || resized;
150
+ }
151
+ export function releaseGlRenderCache(state, cache) {
152
+ const targets = getTargets(state);
153
+ const target = targets.get(cache);
154
+ if (target === undefined)
155
+ return;
156
+ // A GlRenderTarget owns a framebuffer and texture; GC will not free them.
157
+ destroyGlRenderTarget(state, target);
158
+ targets.delete(cache);
159
+ }
160
+ function drawGlRenderCache(state, renderProxy) {
161
+ const cache = getRenderProxyCache(state, renderProxy.source);
162
+ if (cache === null)
163
+ return;
164
+ const target = getTargets(state).get(cache);
165
+ if (target === undefined)
166
+ return;
167
+ // Drain pending batched geometry before the immediate composite quad. Like every other
168
+ // immediate-draw renderer (RichText, Video, Scale9), this bypasses the sprite batch; without the
169
+ // flush the cached result draws ahead of geometry submitted earlier in the walk, which only
170
+ // flushes at the end — producing out-of-order replay (a doubled image on Gl).
171
+ flushGlSpriteBatch(state);
172
+ // renderProxy.transform2D already carries the cache placement transform (folded in by the
173
+ // adapter), so the target composites with an identity offset.
174
+ drawGlRenderTargetResult(state, renderProxy, target, _identity);
175
+ }
176
+ function getTargets(state) {
177
+ let targets = _renderCacheTargets.get(state);
178
+ if (targets === undefined) {
179
+ targets = new WeakMap();
180
+ _renderCacheTargets.set(state, targets);
181
+ }
182
+ return targets;
183
+ }
184
+ export const defaultGlRenderCacheRenderer = {
185
+ createData: noopRendererData,
186
+ submit: drawGlRenderCache,
187
+ };
188
+ // The screen state owns each cache's target, keyed by the handle, so one handle can be
189
+ // composited by several states without the handle carrying a backend resource.
190
+ const _renderCacheTargets = new WeakMap();
191
+ // Links an offscreen cache state back to the screen state whose targets it bakes into.
192
+ const _cacheStateScreen = new WeakMap();
193
+ const _bounds = createRectangle();
194
+ const _renderTransform = createMatrix();
195
+ const _identity = createMatrix();
196
+ //# sourceMappingURL=glCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glCache.js","sourceRoot":"","sources":["../src/glCache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { GlRenderState } from '@flighthq/types';
2
+ export declare function enableGlClipSupport(state: GlRenderState): void;
3
+ //# sourceMappingURL=glClip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glClip.d.ts","sourceRoot":"","sources":["../src/glClip.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA4B,aAAa,EAAiB,MAAM,iBAAiB,CAAC;AAO9F,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAE9D"}
package/dist/glClip.js ADDED
@@ -0,0 +1,46 @@
1
+ import { getGlRenderStateRuntime } from '@flighthq/render-gl';
2
+ import { popGlClipContours, pushGlClipContours } from './glClipContours';
3
+ import { popGlClipRectangle, pushGlClipRectangle } from './glClipRectangle';
4
+ // Clip support installs the unified clip hooks. Masks are RETIRED — a former mask is now a path
5
+ // ClipRegion (createClipRegionFromPath + setNode2DClip), realized by the contour stencil below.
6
+ export function enableGlClipSupport(state) {
7
+ state.displayObjectClipHooks = webglClipHooks;
8
+ }
9
+ // A clip is realized as a scissor (rect form) or stencil-then-cover (contour form). These are
10
+ // independent hardware gates that AND together when nested. `clipForms` records each pushed clip's
11
+ // form so the depth-driven unwind un-installs the right gate.
12
+ function popOneGlClip(state) {
13
+ const form = getGlRenderStateRuntime(state).clipForms.pop();
14
+ if (form === 'contour')
15
+ popGlClipContours(state);
16
+ else
17
+ popGlClipRectangle(state);
18
+ }
19
+ const webglClipHooks = {
20
+ finalize(state) {
21
+ const runtime = getGlRenderStateRuntime(state);
22
+ while (runtime.clipForms.length > 0)
23
+ popOneGlClip(state);
24
+ },
25
+ popClip(state, data, source) {
26
+ const runtime = getGlRenderStateRuntime(state);
27
+ const target = data.clipDepth - (source.clip != null ? 1 : 0);
28
+ while (runtime.clipForms.length > target)
29
+ popOneGlClip(state);
30
+ },
31
+ pushClip(state, data, source) {
32
+ const runtime = getGlRenderStateRuntime(state);
33
+ const clip = source.clip;
34
+ if (clip === null)
35
+ return;
36
+ if (clip.contours === null) {
37
+ pushGlClipRectangle(state, clip.rect, data.transform2D);
38
+ runtime.clipForms.push('rect');
39
+ }
40
+ else {
41
+ pushGlClipContours(state, clip.contours, clip.winding, data.transform2D);
42
+ runtime.clipForms.push('contour');
43
+ }
44
+ },
45
+ };
46
+ //# sourceMappingURL=glClip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glClip.js","sourceRoot":"","sources":["../src/glClip.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAG9D,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE5E,gGAAgG;AAChG,gGAAgG;AAChG,MAAM,UAAU,mBAAmB,CAAC,KAAoB;IACtD,KAAK,CAAC,sBAAsB,GAAG,cAAc,CAAC;AAChD,CAAC;AAED,8FAA8F;AAC9F,mGAAmG;AACnG,8DAA8D;AAC9D,SAAS,YAAY,CAAC,KAAoB;IACxC,MAAM,IAAI,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;IAC5D,IAAI,IAAI,KAAK,SAAS;QAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC;;QAC5C,kBAAkB,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,cAAc,GAAqB;IACvC,QAAQ,CAAC,KAAoB;QAC3B,MAAM,OAAO,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;QAC/C,OAAO,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,CAAC,KAAoB,EAAE,IAAmB,EAAE,MAAc;QAC/D,MAAM,OAAO,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,OAAO,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,MAAM;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IAChE,CAAC;IACD,QAAQ,CAAC,KAAoB,EAAE,IAAmB,EAAE,MAAc;QAChE,MAAM,OAAO,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACzB,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO;QAC1B,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YAC3B,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YACxD,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;YACzE,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { GlRenderState, Matrix, PathWinding } from '@flighthq/types';
2
+ export declare function popGlClipContours(state: GlRenderState): void;
3
+ export declare function pushGlClipContours(state: GlRenderState, contours: readonly (readonly number[])[], winding: PathWinding, worldTransform: Readonly<Matrix>): void;
4
+ //# sourceMappingURL=glClipContours.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glClipContours.d.ts","sourceRoot":"","sources":["../src/glClipContours.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAsC1E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAa5D;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,EACxC,OAAO,EAAE,WAAW,EACpB,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,GAC/B,IAAI,CAiDN"}
@@ -0,0 +1,148 @@
1
+ import { createGlProgram } from '@flighthq/render-gl';
2
+ import { getGlRenderStateRuntime } from '@flighthq/render-gl';
3
+ import { flushGlSpriteBatch } from './glSpriteBatch';
4
+ // Stencil-then-cover fill of arbitrary flattened contours, used to realize a *path* ClipRegion exactly
5
+ // (crisp at any zoom — the contours are transformed in the vertex shader each frame, never cached as a
6
+ // texture). This is the contour counterpart to webglClipRectangle's scissor and replaces the old mask
7
+ // stencil. It needs no display node — just geometry + a winding rule.
8
+ //
9
+ // MODEL: a single-level contour clip gates content to the polygon's covered pixels. PHASE 1 accumulates
10
+ // the winding into the stencil with color off (non-zero: front/back INCR/DECR_WRAP; even-odd: INVERT);
11
+ // PHASE 2 enables color and sets the stencil test so only covered pixels pass (non-zero: != 0; even-odd:
12
+ // low bit set). state.currentMaskDepth tracks whether the gate is live (it is the "a stencil test is
13
+ // active" signal the rest of the GPU path keys off) and triggers a stencil clear when a sibling clip
14
+ // opens at depth 0. Scissor (rect) clips compose independently via the scissor test. Nested *contour*
15
+ // clips share one stencil buffer and are not re-derived on pop — nest a contour inside a rect/scissor
16
+ // clip when ANDing is needed (documented in popGlClipContours).
17
+ //
18
+ // Verified via the `mask` functional capture (canvas/dom/webgl agree). The clip program must keep
19
+ // state.currentProgram in sync (see pushGlClipContours) so content draws re-bind their own program.
20
+ // Position-only program: transform contour points (clip-local) by the node world transform, then by the
21
+ // backend's pixels->clip projection. Fragment writes nothing — color is masked off; only stencil moves.
22
+ const VERTEX_SOURCE = `
23
+ attribute vec2 a_position;
24
+ uniform mat3 u_worldMatrix; // node world transform2D (a,b,c,d,tx,ty) lifted to mat3
25
+ uniform mat3 u_projection; // device pixels -> clip space (same one the sprite/shape shaders use)
26
+ void main() {
27
+ vec3 clip = u_projection * (u_worldMatrix * vec3(a_position, 1.0));
28
+ gl_Position = vec4(clip.xy, 0.0, 1.0);
29
+ }
30
+ `;
31
+ const FRAGMENT_SOURCE = `
32
+ precision mediump float;
33
+ void main() { gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); }
34
+ `;
35
+ export function popGlClipContours(state) {
36
+ flushGlSpriteBatch(state);
37
+ const runtime = getGlRenderStateRuntime(state);
38
+ const gl = state.gl;
39
+ const nextDepth = Math.max(0, (runtime.currentMaskDepth ?? 0) - 1);
40
+ runtime.currentMaskDepth = nextDepth;
41
+ // Single-level contour clips are the common case; the outermost pop turns the stencil gate off. Nested
42
+ // contour clips share one stencil buffer and are not re-derived on pop (a documented limitation — nest
43
+ // a contour inside a rect/scissor clip instead, which composes independently).
44
+ if (nextDepth === 0) {
45
+ gl.disable(gl.STENCIL_TEST);
46
+ gl.stencilMask(0xff);
47
+ }
48
+ }
49
+ export function pushGlClipContours(state, contours, winding, worldTransform) {
50
+ flushGlSpriteBatch(state);
51
+ const runtime = getGlRenderStateRuntime(state);
52
+ const gl = state.gl;
53
+ const depth = runtime.currentMaskDepth ?? 0;
54
+ if (depth === 0) {
55
+ gl.enable(gl.STENCIL_TEST);
56
+ gl.stencilMask(0xff);
57
+ gl.clear(gl.STENCIL_BUFFER_BIT);
58
+ }
59
+ ensureClipProgram(state);
60
+ const program = clipProgramFor(state);
61
+ gl.useProgram(program.program);
62
+ // Content draws skip gl.useProgram when state.currentProgram already matches their program. Record the
63
+ // clip program here so the next content draw detects the change and re-binds — otherwise it would set
64
+ // its uniforms against the clip program (INVALID_OPERATION: location not from the associated program).
65
+ runtime.currentProgram = program.program;
66
+ uploadClipUniforms(state, program, worldTransform);
67
+ // PHASE 1 — accumulate the polygon's winding into the stencil with color writes off. Non-zero uses
68
+ // separate front/back INCR/DECR_WRAP (interior ends up != 0); even-odd uses INVERT (interior ends odd).
69
+ gl.colorMask(false, false, false, false);
70
+ gl.stencilMask(0xff);
71
+ gl.disable(gl.CULL_FACE); // non-zero needs both faces rasterized; 2D content leaves culling off anyway
72
+ if (winding === 'evenOdd') {
73
+ gl.stencilFunc(gl.ALWAYS, 0, 0xff);
74
+ gl.stencilOp(gl.KEEP, gl.KEEP, gl.INVERT);
75
+ }
76
+ else {
77
+ gl.stencilFunc(gl.ALWAYS, 0, 0xff);
78
+ gl.stencilOpSeparate(gl.FRONT, gl.KEEP, gl.KEEP, gl.INCR_WRAP);
79
+ gl.stencilOpSeparate(gl.BACK, gl.KEEP, gl.KEEP, gl.DECR_WRAP);
80
+ }
81
+ drawClipContours(state, program, contours);
82
+ // PHASE 2 — enable color and gate subsequent content to the covered pixels: non-zero passes where the
83
+ // accumulated count != 0; even-odd passes where the low bit is set. stencilMask 0 so content cannot
84
+ // disturb the coverage. The gate persists through the content draws until popGlClipContours.
85
+ gl.colorMask(true, true, true, true);
86
+ gl.stencilMask(0x00);
87
+ if (winding === 'evenOdd') {
88
+ gl.stencilFunc(gl.EQUAL, 0x1, 0x1);
89
+ }
90
+ else {
91
+ gl.stencilFunc(gl.NOTEQUAL, 0x0, 0xff);
92
+ }
93
+ gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
94
+ runtime.currentMaskDepth = depth + 1;
95
+ }
96
+ const clipPrograms = new WeakMap();
97
+ function clipProgramFor(state) {
98
+ return clipPrograms.get(state.gl);
99
+ }
100
+ function ensureClipProgram(state) {
101
+ const gl = state.gl;
102
+ if (clipPrograms.has(gl))
103
+ return;
104
+ const program = compileProgram(gl, VERTEX_SOURCE, FRAGMENT_SOURCE);
105
+ clipPrograms.set(gl, {
106
+ program,
107
+ buffer: gl.createBuffer(),
108
+ positionLocation: gl.getAttribLocation(program, 'a_position'),
109
+ worldMatrixLocation: gl.getUniformLocation(program, 'u_worldMatrix'),
110
+ projectionLocation: gl.getUniformLocation(program, 'u_projection'),
111
+ });
112
+ }
113
+ function compileProgram(gl, vertex, fragment) {
114
+ return createGlProgram(gl, vertex, fragment, 'Clip-contours');
115
+ }
116
+ function uploadClipUniforms(state, program, m) {
117
+ const gl = state.gl;
118
+ // mat3 column-major from Matrix(a,b,c,d,tx,ty).
119
+ // prettier-ignore
120
+ gl.uniformMatrix3fv(program.worldMatrixLocation, false, [m.a, m.b, 0, m.c, m.d, 0, m.tx, m.ty, 1]);
121
+ gl.uniformMatrix3fv(program.projectionLocation, false, getProjectionMat3(state));
122
+ }
123
+ function drawClipContours(state, program, contours) {
124
+ const gl = state.gl;
125
+ gl.bindBuffer(gl.ARRAY_BUFFER, program.buffer);
126
+ gl.enableVertexAttribArray(program.positionLocation);
127
+ gl.vertexAttribPointer(program.positionLocation, 2, gl.FLOAT, false, 0, 0);
128
+ for (let c = 0; c < contours.length; c++) {
129
+ const contour = contours[c];
130
+ if (contour.length < 6)
131
+ continue; // need at least a triangle
132
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(contour), gl.STREAM_DRAW);
133
+ // TRIANGLE_FAN fills the (possibly concave) polygon into the stencil; winding op handles correctness.
134
+ gl.drawArrays(gl.TRIANGLE_FAN, 0, contour.length >> 1);
135
+ }
136
+ }
137
+ // Device pixels -> clip space for the current viewport / render target. This is the same column-major
138
+ // mat3 the sprite/shape batch builds in setGlQuadBatchWorldAndTexture, so a clip's contours and the
139
+ // content it clips land in identical clip space (the clip stays pixel-exact under the node transform).
140
+ function getProjectionMat3(state) {
141
+ const runtime = getGlRenderStateRuntime(state);
142
+ const w = (runtime.renderTargetViewport ?? state.canvas).width || 1;
143
+ const h = (runtime.renderTargetViewport ?? state.canvas).height || 1;
144
+ // pixels (origin top-left, y down) -> clip space (-1..1, y up)
145
+ // prettier-ignore
146
+ return new Float32Array([2 / w, 0, 0, 0, -2 / h, 0, -1, 1, 1]);
147
+ }
148
+ //# sourceMappingURL=glClipContours.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glClipContours.js","sourceRoot":"","sources":["../src/glClipContours.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { GlRenderState, MatrixLike, RectangleLike } from '@flighthq/types';
2
+ export declare function popGlClipRectangle(state: GlRenderState): void;
3
+ export declare function pushGlClipRectangle(state: GlRenderState, rect: Readonly<RectangleLike>, transform: Readonly<MatrixLike>): void;
4
+ //# sourceMappingURL=glClipRectangle.d.ts.map