@supersoniks/concorde 4.9.97-visual-stack.0 → 4.9.98-visual-stack.1

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 (171) hide show
  1. package/build-infos.json +1 -1
  2. package/concorde-3d.bundle.js +201 -152
  3. package/concorde-3d.es.js +14621 -13823
  4. package/concorde-core.bundle.js +1 -1
  5. package/concorde-core.es.js +1 -1
  6. package/concorde-hugging-face-infer.bundle.js +1 -1
  7. package/concorde-hugging-face-infer.es.js +1 -1
  8. package/concorde-shader.bundle.js +31 -20
  9. package/concorde-shader.es.js +3236 -2865
  10. package/concorde-webgpu.bundle.js +43 -32
  11. package/concorde-webgpu.es.js +2977 -2618
  12. package/dist/concorde-3d.bundle.js +201 -152
  13. package/dist/concorde-3d.es.js +14621 -13823
  14. package/dist/concorde-core.bundle.js +1 -1
  15. package/dist/concorde-core.es.js +1 -1
  16. package/dist/concorde-hugging-face-infer.bundle.js +1 -1
  17. package/dist/concorde-hugging-face-infer.es.js +1 -1
  18. package/dist/concorde-shader.bundle.js +31 -20
  19. package/dist/concorde-shader.es.js +3236 -2865
  20. package/dist/concorde-webgpu.bundle.js +43 -32
  21. package/dist/concorde-webgpu.es.js +2977 -2618
  22. package/dist/js/core/components/functional/3d/3d.js +100 -2
  23. package/dist/js/core/components/functional/3d/3d.js.map +1 -1
  24. package/dist/js/core/components/functional/3d/constants.js +3 -0
  25. package/dist/js/core/components/functional/3d/constants.js.map +1 -1
  26. package/dist/js/core/components/functional/3d/ensure.js +6 -3
  27. package/dist/js/core/components/functional/3d/ensure.js.map +1 -1
  28. package/dist/js/core/components/functional/3d/form-params.js +2 -0
  29. package/dist/js/core/components/functional/3d/form-params.js.map +1 -1
  30. package/dist/js/core/components/functional/3d/frame-source.js +22 -0
  31. package/dist/js/core/components/functional/3d/frame-source.js.map +1 -0
  32. package/dist/js/core/components/functional/3d/life.js +2 -1
  33. package/dist/js/core/components/functional/3d/life.js.map +1 -1
  34. package/dist/js/core/components/functional/3d/out-publish.js +3 -2
  35. package/dist/js/core/components/functional/3d/out-publish.js.map +1 -1
  36. package/dist/js/core/components/functional/3d/playback.js +6 -1
  37. package/dist/js/core/components/functional/3d/playback.js.map +1 -1
  38. package/dist/js/core/components/functional/3d/post-bind.js +207 -0
  39. package/dist/js/core/components/functional/3d/post-bind.js.map +1 -0
  40. package/dist/js/core/components/functional/3d/post-channels.js +39 -0
  41. package/dist/js/core/components/functional/3d/post-channels.js.map +1 -0
  42. package/dist/js/core/components/functional/3d/post-fx.js +495 -0
  43. package/dist/js/core/components/functional/3d/post-fx.js.map +1 -0
  44. package/dist/js/core/components/functional/3d/props.js +142 -0
  45. package/dist/js/core/components/functional/3d/props.js.map +1 -1
  46. package/dist/js/core/components/functional/3d/reload.js +5 -0
  47. package/dist/js/core/components/functional/3d/reload.js.map +1 -1
  48. package/dist/js/core/components/functional/3d/runtime.js +80 -3
  49. package/dist/js/core/components/functional/3d/runtime.js.map +1 -1
  50. package/dist/js/core/components/functional/3d/scene-runtime.js +1 -1
  51. package/dist/js/core/components/functional/3d/scene-runtime.js.map +1 -1
  52. package/dist/js/core/components/functional/3d/tune.js +21 -0
  53. package/dist/js/core/components/functional/3d/tune.js.map +1 -1
  54. package/dist/js/core/components/functional/3d/updated.js +13 -1
  55. package/dist/js/core/components/functional/3d/updated.js.map +1 -1
  56. package/dist/js/core/components/functional/shader/gl-runtime.js +280 -31
  57. package/dist/js/core/components/functional/shader/gl-runtime.js.map +1 -1
  58. package/dist/js/core/components/functional/shader/shader.js +207 -61
  59. package/dist/js/core/components/functional/shader/shader.js.map +1 -1
  60. package/dist/js/core/components/functional/shader/shadertoy-prelude.js +39 -5
  61. package/dist/js/core/components/functional/shader/shadertoy-prelude.js.map +1 -1
  62. package/dist/js/core/components/functional/shader/types.js +58 -7
  63. package/dist/js/core/components/functional/shader/types.js.map +1 -1
  64. package/dist/js/core/components/functional/webgpu/gl-fallback.js +27 -6
  65. package/dist/js/core/components/functional/webgpu/gl-fallback.js.map +1 -1
  66. package/dist/js/core/components/functional/webgpu/gpu-runtime.js +115 -13
  67. package/dist/js/core/components/functional/webgpu/gpu-runtime.js.map +1 -1
  68. package/dist/js/core/components/functional/webgpu/helpers.js +8 -2
  69. package/dist/js/core/components/functional/webgpu/helpers.js.map +1 -1
  70. package/dist/js/core/components/functional/webgpu/webgpu.js +43 -1
  71. package/dist/js/core/components/functional/webgpu/webgpu.js.map +1 -1
  72. package/dist/js/core/utils/mediaRef.js +86 -0
  73. package/dist/js/core/utils/mediaRef.js.map +1 -1
  74. package/dist/types/core/components/functional/3d/3d.d.ts +31 -3
  75. package/dist/types/core/components/functional/3d/3d.d.ts.map +1 -1
  76. package/dist/types/core/components/functional/3d/constants.d.ts +1 -1
  77. package/dist/types/core/components/functional/3d/constants.d.ts.map +1 -1
  78. package/dist/types/core/components/functional/3d/ensure.d.ts +3 -0
  79. package/dist/types/core/components/functional/3d/ensure.d.ts.map +1 -1
  80. package/dist/types/core/components/functional/3d/form-params.d.ts.map +1 -1
  81. package/dist/types/core/components/functional/3d/frame-source.d.ts +23 -0
  82. package/dist/types/core/components/functional/3d/frame-source.d.ts.map +1 -0
  83. package/dist/types/core/components/functional/3d/life.d.ts +2 -0
  84. package/dist/types/core/components/functional/3d/life.d.ts.map +1 -1
  85. package/dist/types/core/components/functional/3d/out-publish.d.ts +1 -0
  86. package/dist/types/core/components/functional/3d/out-publish.d.ts.map +1 -1
  87. package/dist/types/core/components/functional/3d/playback.d.ts +9 -0
  88. package/dist/types/core/components/functional/3d/playback.d.ts.map +1 -1
  89. package/dist/types/core/components/functional/3d/post-bind.d.ts +52 -0
  90. package/dist/types/core/components/functional/3d/post-bind.d.ts.map +1 -0
  91. package/dist/types/core/components/functional/3d/post-channels.d.ts +40 -0
  92. package/dist/types/core/components/functional/3d/post-channels.d.ts.map +1 -0
  93. package/dist/types/core/components/functional/3d/post-fx.d.ts +73 -0
  94. package/dist/types/core/components/functional/3d/post-fx.d.ts.map +1 -0
  95. package/dist/types/core/components/functional/3d/props.d.ts +42 -0
  96. package/dist/types/core/components/functional/3d/props.d.ts.map +1 -1
  97. package/dist/types/core/components/functional/3d/reload.d.ts +3 -0
  98. package/dist/types/core/components/functional/3d/reload.d.ts.map +1 -1
  99. package/dist/types/core/components/functional/3d/runtime.d.ts +16 -1
  100. package/dist/types/core/components/functional/3d/runtime.d.ts.map +1 -1
  101. package/dist/types/core/components/functional/3d/scene-runtime.d.ts +1 -1
  102. package/dist/types/core/components/functional/3d/scene-runtime.d.ts.map +1 -1
  103. package/dist/types/core/components/functional/3d/tune.d.ts +5 -0
  104. package/dist/types/core/components/functional/3d/tune.d.ts.map +1 -1
  105. package/dist/types/core/components/functional/3d/types.d.ts +16 -0
  106. package/dist/types/core/components/functional/3d/types.d.ts.map +1 -1
  107. package/dist/types/core/components/functional/3d/updated.d.ts.map +1 -1
  108. package/dist/types/core/components/functional/shader/gl-runtime.d.ts +53 -2
  109. package/dist/types/core/components/functional/shader/gl-runtime.d.ts.map +1 -1
  110. package/dist/types/core/components/functional/shader/shader.d.ts +41 -9
  111. package/dist/types/core/components/functional/shader/shader.d.ts.map +1 -1
  112. package/dist/types/core/components/functional/shader/shadertoy-prelude.d.ts +16 -2
  113. package/dist/types/core/components/functional/shader/shadertoy-prelude.d.ts.map +1 -1
  114. package/dist/types/core/components/functional/shader/types.d.ts +35 -5
  115. package/dist/types/core/components/functional/shader/types.d.ts.map +1 -1
  116. package/dist/types/core/components/functional/webgpu/gl-fallback.d.ts +4 -0
  117. package/dist/types/core/components/functional/webgpu/gl-fallback.d.ts.map +1 -1
  118. package/dist/types/core/components/functional/webgpu/gpu-runtime.d.ts +14 -0
  119. package/dist/types/core/components/functional/webgpu/gpu-runtime.d.ts.map +1 -1
  120. package/dist/types/core/components/functional/webgpu/helpers.d.ts +1 -0
  121. package/dist/types/core/components/functional/webgpu/helpers.d.ts.map +1 -1
  122. package/dist/types/core/components/functional/webgpu/webgpu.d.ts +11 -1
  123. package/dist/types/core/components/functional/webgpu/webgpu.d.ts.map +1 -1
  124. package/dist/types/core/utils/mediaRef.d.ts +34 -0
  125. package/dist/types/core/utils/mediaRef.d.ts.map +1 -1
  126. package/package.json +49 -1
  127. package/src/core/components/functional/3d/3d.md +46 -3
  128. package/src/core/components/functional/3d/3d.spec.ts +42 -0
  129. package/src/core/components/functional/3d/3d.ts +112 -3
  130. package/src/core/components/functional/3d/constants.ts +3 -0
  131. package/src/core/components/functional/3d/ensure.ts +11 -3
  132. package/src/core/components/functional/3d/form-params.ts +2 -0
  133. package/src/core/components/functional/3d/frame-source.ts +30 -0
  134. package/src/core/components/functional/3d/life.ts +4 -1
  135. package/src/core/components/functional/3d/out-publish.ts +4 -3
  136. package/src/core/components/functional/3d/playback.ts +13 -1
  137. package/src/core/components/functional/3d/post-bind.ts +262 -0
  138. package/src/core/components/functional/3d/post-channels.spec.ts +36 -0
  139. package/src/core/components/functional/3d/post-channels.ts +69 -0
  140. package/src/core/components/functional/3d/post-fx.ts +594 -0
  141. package/src/core/components/functional/3d/props.ts +45 -0
  142. package/src/core/components/functional/3d/reload.ts +8 -0
  143. package/src/core/components/functional/3d/runtime.ts +93 -4
  144. package/src/core/components/functional/3d/scene-runtime.ts +3 -0
  145. package/src/core/components/functional/3d/tune.ts +21 -0
  146. package/src/core/components/functional/3d/types.ts +14 -0
  147. package/src/core/components/functional/3d/updated.ts +17 -1
  148. package/src/core/components/functional/shader/gl-runtime.ts +374 -36
  149. package/src/core/components/functional/shader/shader.md +36 -11
  150. package/src/core/components/functional/shader/shader.spec.ts +350 -3
  151. package/src/core/components/functional/shader/shader.ts +236 -59
  152. package/src/core/components/functional/shader/shadertoy-prelude.ts +49 -5
  153. package/src/core/components/functional/shader/types.ts +92 -13
  154. package/src/core/components/functional/webgpu/gl-fallback.ts +28 -4
  155. package/src/core/components/functional/webgpu/gpu-runtime.ts +154 -18
  156. package/src/core/components/functional/webgpu/helpers.ts +8 -2
  157. package/src/core/components/functional/webgpu/webgpu.md +13 -2
  158. package/src/core/components/functional/webgpu/webgpu.spec.ts +37 -0
  159. package/src/core/components/functional/webgpu/webgpu.ts +48 -1
  160. package/src/core/utils/mediaRef.spec.ts +61 -0
  161. package/src/core/utils/mediaRef.ts +108 -0
  162. package/src/docs/_misc/visual-stack.md +37 -3
  163. package/src/docs/components/docs-demo-sources.ts +42 -0
  164. package/src/docs/docs.ts +3 -0
  165. package/src/docs/example/docs-3d-post-depth-demo.ts +68 -0
  166. package/src/docs/example/docs-3d-shader-live-demo.ts +98 -0
  167. package/src/docs/example/docs-3d-webgpu-live-demo.ts +83 -0
  168. package/src/docs/example/docs-harris-webgpu-demo.ts +53 -55
  169. package/src/docs/search/docs-search.json +2583 -863
  170. package/src/tsconfig.json +36 -0
  171. package/src/tsconfig.tsbuildinfo +1 -1
@@ -7,12 +7,49 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { css, html, LitElement } from "lit";
8
8
  import { customElement, property, state } from "lit/decorators.js";
9
9
  import HTML from "@supersoniks/concorde/core/utils/HTML";
10
- import { revokeMediaUrls, toMediaUrl } from "@supersoniks/concorde/core/utils/mediaRef";
10
+ import { revokeMediaUrls, toMediaUrl, mediaElementKey, lookupLiveElement, FrameConsumerRegistry } from "@supersoniks/concorde/core/utils/mediaRef";
11
11
  import { PublisherManager } from "@supersoniks/concorde/utils";
12
12
  import { parseChannelSource, ShaderToyRuntime, } from "./gl-runtime";
13
- import { ShaderCompileError, findPeaks, meanRgba, parseExtractPass, parseHoverParam, roiToPixels, } from "./types";
13
+ import { ShaderCompileError, channelsUseSelf, findPeaks, meanRgba, parseBufferFormat, parseExtractPass, parseHoverParam, parseReleaseOffscreen, roiToPixels, rgbaToUint8, shouldReleaseWhenOffscreen, } from "./types";
14
14
  const tagName = "sonic-shader";
15
15
  const MAX_PATCH_PX = 128;
16
+ /** Clés qui forcent une recompilation / recreate FBO. */
17
+ const PROGRAM_KEYS = [
18
+ "image",
19
+ "bufferA",
20
+ "bufferB",
21
+ "bufferC",
22
+ "bufferD",
23
+ "common",
24
+ "bufferFormat",
25
+ ];
26
+ /** Clés qui ne font que re-lier les textures (pas de rebuild). */
27
+ const CHANNEL_KEYS = [
28
+ "channel0",
29
+ "channel1",
30
+ "channel2",
31
+ "channel3",
32
+ "imageCh0",
33
+ "imageCh1",
34
+ "imageCh2",
35
+ "imageCh3",
36
+ "bufferACh0",
37
+ "bufferACh1",
38
+ "bufferACh2",
39
+ "bufferACh3",
40
+ "bufferBCh0",
41
+ "bufferBCh1",
42
+ "bufferBCh2",
43
+ "bufferBCh3",
44
+ "bufferCCh0",
45
+ "bufferCCh1",
46
+ "bufferCCh2",
47
+ "bufferCCh3",
48
+ "bufferDCh0",
49
+ "bufferDCh1",
50
+ "bufferDCh2",
51
+ "bufferDCh3",
52
+ ];
16
53
  /**
17
54
  * Champs méta publiés vers le out-dataProvider.
18
55
  * `param0…3` sont exclus du gate « consommateur » : un `sonic-input name="param0"`
@@ -76,7 +113,7 @@ function toNum(v, fallback) {
76
113
  }
77
114
  return fallback;
78
115
  }
79
- /** Valeur canal depuis DP : string (url ou buffer-a) | MediaRef → url. */
116
+ /** Valeur canal depuis DP : string (url, buffer-a, #id) | MediaRef → url | { element }. */
80
117
  function channelFormValue(value) {
81
118
  if (value === null || value === "")
82
119
  return "";
@@ -85,10 +122,17 @@ function channelFormValue(value) {
85
122
  const url = toMediaUrl(value);
86
123
  if (url)
87
124
  return url;
88
- if (value && typeof value === "object")
125
+ if (value && typeof value === "object") {
126
+ const el = value.element;
127
+ const key = mediaElementKey(el);
128
+ if (key)
129
+ return key;
89
130
  return undefined;
131
+ }
90
132
  return "";
91
133
  }
134
+ /** Exposé pour tests. */
135
+ export { channelFormValue };
92
136
  function parseRois(value) {
93
137
  if (!Array.isArray(value))
94
138
  return [];
@@ -223,11 +267,19 @@ let SonicShader = class SonicShader extends LitElement {
223
267
  /** Vitesse d’easing hover on/off (1/s, défaut 10). */
224
268
  this.hoverSpeed = 10;
225
269
  /**
226
- * Libère le contexte WebGL hors viewport (défaut true).
227
- * Les navigateurs limitent ~8–16 contextes.
270
+ * Hors viewport : libère textures/FBO (garde le contexte).
271
+ * `auto` (défaut) : ne libère pas si une passe lit `self`.
272
+ * `true` / `false` forcent le comportement.
228
273
  */
229
- this.releaseOffscreen = true;
274
+ this.releaseOffscreen = "auto";
230
275
  this.dprMax = 2;
276
+ /**
277
+ * Format des buffers A–D : `rgba8` (défaut) | `rgba16f` | `rgba32f`.
278
+ * Attribut reflété `active-buffer-format` = format réellement utilisé.
279
+ */
280
+ this.bufferFormat = "rgba8";
281
+ /** Format actif après repli éventuel (lecture seule, reflect). */
282
+ this.activeBufferFormat = "rgba8";
231
283
  /** Generic float uniforms `uParam0`…`uParam3` (no shader rebuild). */
232
284
  this.param0 = 0;
233
285
  this.param1 = 0;
@@ -282,6 +334,8 @@ let SonicShader = class SonicShader extends LitElement {
282
334
  this.startTime = 0;
283
335
  this.lastTime = 0;
284
336
  this.frame = 0;
337
+ /** Incrémenté après chaque render (contrat SonicFrameSource). */
338
+ this.frameSeq = 0;
285
339
  this.mouseVec = [0, 0, 0, 0];
286
340
  /** Cible pointeur (px drawing buffer, origine bas-gauche). */
287
341
  this.mouseTarget = [0, 0];
@@ -307,6 +361,9 @@ let SonicShader = class SonicShader extends LitElement {
307
361
  this.resizeObserver = null;
308
362
  this.intersectionObserver = null;
309
363
  this.rebuildToken = 0;
364
+ /** Annule un `rebindChannels` en vol si rebuild / release intervient. */
365
+ this.rebindToken = 0;
366
+ this.frameConsumers = new FrameConsumerRegistry();
310
367
  this.ready = false;
311
368
  this.formPublisher = null;
312
369
  this.outPublisher = null;
@@ -327,6 +384,7 @@ let SonicShader = class SonicShader extends LitElement {
327
384
  if (this.releasing)
328
385
  return;
329
386
  this.rebuildToken++;
387
+ this.rebindToken++;
330
388
  this.stopLoop();
331
389
  this.ready = false;
332
390
  this.runtime = null;
@@ -454,9 +512,11 @@ let SonicShader = class SonicShader extends LitElement {
454
512
  }
455
513
  this.pendingRevokeUrls = [];
456
514
  this.stopLoop();
515
+ this.frameConsumers.clear();
457
516
  this.resizeObserver?.disconnect();
458
517
  this.intersectionObserver?.disconnect();
459
518
  this.rebuildToken++;
519
+ this.rebindToken++;
460
520
  this.ready = false;
461
521
  this.releasing = true;
462
522
  this.runtime?.dispose(true); // libère le slot navigateur
@@ -476,7 +536,7 @@ let SonicShader = class SonicShader extends LitElement {
476
536
  this.bindOutPublisher();
477
537
  this.bindExtractPublisher();
478
538
  requestAnimationFrame(() => {
479
- if (this.inView || !this.releaseOffscreen) {
539
+ if (this.inView || !this.wantsReleaseOffscreen()) {
480
540
  void this.ensureRuntime();
481
541
  }
482
542
  });
@@ -484,44 +544,20 @@ let SonicShader = class SonicShader extends LitElement {
484
544
  updated(changed) {
485
545
  if (!this.runtime)
486
546
  return;
487
- const shaderKeys = [
488
- "image",
489
- "bufferA",
490
- "bufferB",
491
- "bufferC",
492
- "bufferD",
493
- "common",
494
- "channel0",
495
- "channel1",
496
- "channel2",
497
- "channel3",
498
- "imageCh0",
499
- "imageCh1",
500
- "imageCh2",
501
- "imageCh3",
502
- "bufferACh0",
503
- "bufferACh1",
504
- "bufferACh2",
505
- "bufferACh3",
506
- "bufferBCh0",
507
- "bufferBCh1",
508
- "bufferBCh2",
509
- "bufferBCh3",
510
- "bufferCCh0",
511
- "bufferCCh1",
512
- "bufferCCh2",
513
- "bufferCCh3",
514
- "bufferDCh0",
515
- "bufferDCh1",
516
- "bufferDCh2",
517
- "bufferDCh3",
518
- ];
519
- if (shaderKeys.some((k) => changed.has(k))) {
547
+ const programChanged = PROGRAM_KEYS.some((k) => changed.has(k));
548
+ const channelChanged = CHANNEL_KEYS.some((k) => changed.has(k));
549
+ if (programChanged) {
520
550
  void this.rebuild();
521
551
  }
552
+ else if (channelChanged) {
553
+ void this.rebindChannels();
554
+ }
522
555
  if (changed.has("play")) {
523
556
  this.syncPlayback();
524
557
  }
558
+ if (changed.has("releaseOffscreen") || channelChanged) {
559
+ this.syncVisibility();
560
+ }
525
561
  if (changed.has("dataProvider") ||
526
562
  changed.has("outDataProvider") ||
527
563
  changed.has("extractDataProvider")) {
@@ -656,6 +692,7 @@ let SonicShader = class SonicShader extends LitElement {
656
692
  */
657
693
  releaseRuntime() {
658
694
  this.rebuildToken++;
695
+ this.rebindToken++;
659
696
  this.stopLoop();
660
697
  this.ready = false;
661
698
  this.releasing = true;
@@ -668,6 +705,30 @@ let SonicShader = class SonicShader extends LitElement {
668
705
  return (this.renderRoot?.querySelector("canvas") ??
669
706
  null);
670
707
  }
708
+ /** Contrat SonicFrameSource — canvas lisible pour un autre sonic-shader. */
709
+ getFrameCanvas() {
710
+ if (!this.ready || !this.runtime || this.runtime.isLost)
711
+ return null;
712
+ return this.getCanvas();
713
+ }
714
+ /** Résout `#id` dans getRootNode() puis document ; clés live `__sonic_frame_`. */
715
+ lookupElement(key) {
716
+ if (!key.startsWith("#"))
717
+ return null;
718
+ const live = lookupLiveElement(key);
719
+ if (live)
720
+ return live;
721
+ const id = key.slice(1);
722
+ if (!id || id.startsWith("__sonic_frame_"))
723
+ return null;
724
+ const root = this.getRootNode();
725
+ if (root instanceof Document || root instanceof ShadowRoot) {
726
+ const el = root.getElementById(id);
727
+ if (el)
728
+ return el;
729
+ }
730
+ return typeof document !== "undefined" ? document.getElementById(id) : null;
731
+ }
671
732
  bindContextEvents() {
672
733
  const canvas = this.getCanvas();
673
734
  canvas?.addEventListener("webglcontextlost", this.onContextLost);
@@ -683,7 +744,7 @@ let SonicShader = class SonicShader extends LitElement {
683
744
  return;
684
745
  this.runtime = null;
685
746
  await this.updateComplete;
686
- if (!this.isConnected || (!this.inView && this.releaseOffscreen))
747
+ if (!this.isConnected || (!this.inView && this.wantsReleaseOffscreen()))
687
748
  return;
688
749
  const canvas = this.getCanvas();
689
750
  if (!canvas)
@@ -691,6 +752,8 @@ let SonicShader = class SonicShader extends LitElement {
691
752
  try {
692
753
  this.errorMessage = "";
693
754
  this.runtime = new ShaderToyRuntime(canvas);
755
+ this.runtime.setElementResolver((key) => this.lookupElement(key));
756
+ this.activeBufferFormat = this.runtime.setBufferFormat(parseBufferFormat(this.bufferFormat));
694
757
  this.bindContextEvents();
695
758
  this.syncSize();
696
759
  await this.rebuild();
@@ -700,7 +763,7 @@ let SonicShader = class SonicShader extends LitElement {
700
763
  }
701
764
  }
702
765
  syncVisibility() {
703
- if (!this.inView && this.releaseOffscreen) {
766
+ if (!this.inView && this.wantsReleaseOffscreen()) {
704
767
  this.releaseRuntime();
705
768
  return;
706
769
  }
@@ -770,9 +833,76 @@ let SonicShader = class SonicShader extends LitElement {
770
833
  }
771
834
  return urls;
772
835
  }
836
+ collectElementKeys(channels) {
837
+ const keys = [];
838
+ for (const chs of channels.values()) {
839
+ for (const c of chs) {
840
+ if (c.kind === "element")
841
+ keys.push(c.key);
842
+ }
843
+ }
844
+ return [...new Set(keys)];
845
+ }
846
+ /** Enregistre les producteurs live (`sonic-3d`…) pour play-offscreen auto. */
847
+ syncFrameConsumers(channels) {
848
+ const els = this.collectElementKeys(channels).map((k) => this.lookupElement(k));
849
+ this.frameConsumers.sync(els);
850
+ }
851
+ /** Map canaux courante (tous les passes). */
852
+ collectPassChannels() {
853
+ const channels = new Map();
854
+ for (const pass of [
855
+ "bufferA",
856
+ "bufferB",
857
+ "bufferC",
858
+ "bufferD",
859
+ "image",
860
+ ]) {
861
+ channels.set(pass, this.buildChannels(pass));
862
+ }
863
+ return channels;
864
+ }
865
+ /** `true` si hors viewport on doit libérer textures/FBO. */
866
+ wantsReleaseOffscreen() {
867
+ return shouldReleaseWhenOffscreen(this.releaseOffscreen, channelsUseSelf(this.collectPassChannels().values()));
868
+ }
869
+ /**
870
+ * Re-lie les canaux sans recompiler ni vider les FBO (Vague A Lot 2).
871
+ */
872
+ async rebindChannels() {
873
+ if (!this.runtime || this.runtime.isLost || !this.image.trim())
874
+ return;
875
+ if (!this.ready) {
876
+ void this.rebuild();
877
+ return;
878
+ }
879
+ const token = ++this.rebindToken;
880
+ const channels = this.collectPassChannels();
881
+ try {
882
+ const urls = this.collectUrls(channels);
883
+ await this.runtime.ensureTextures(urls);
884
+ for (const key of this.collectElementKeys(channels)) {
885
+ this.runtime.ensureElementTexture(key);
886
+ }
887
+ if (token !== this.rebindToken || !this.runtime || this.runtime.isLost) {
888
+ return;
889
+ }
890
+ this.syncFrameConsumers(channels);
891
+ const aspectHint = this.channel0.startsWith("#") ? "" : this.channel0 || urls[0];
892
+ this.applyAspectRatio(aspectHint);
893
+ this.runtime.setPassChannels(channels);
894
+ this.syncSize();
895
+ }
896
+ catch (err) {
897
+ if (token !== this.rebindToken)
898
+ return;
899
+ this.emitError(err);
900
+ }
901
+ }
773
902
  async rebuild() {
774
903
  if (!this.runtime || this.runtime.isLost || !this.image.trim())
775
904
  return;
905
+ this.rebindToken++;
776
906
  const token = ++this.rebuildToken;
777
907
  this.errorMessage = "";
778
908
  const sources = {
@@ -783,24 +913,21 @@ let SonicShader = class SonicShader extends LitElement {
783
913
  bufferC: this.bufferC,
784
914
  bufferD: this.bufferD,
785
915
  };
786
- const channels = new Map();
787
- for (const pass of [
788
- "bufferA",
789
- "bufferB",
790
- "bufferC",
791
- "bufferD",
792
- "image",
793
- ]) {
794
- channels.set(pass, this.buildChannels(pass));
795
- }
916
+ const channels = this.collectPassChannels();
796
917
  try {
797
918
  this.syncSize();
919
+ this.activeBufferFormat = this.runtime.setBufferFormat(parseBufferFormat(this.bufferFormat));
798
920
  const urls = this.collectUrls(channels);
799
921
  await this.runtime.ensureTextures(urls);
922
+ for (const key of this.collectElementKeys(channels)) {
923
+ this.runtime.ensureElementTexture(key);
924
+ }
800
925
  if (token !== this.rebuildToken || !this.runtime || this.runtime.isLost) {
801
926
  return;
802
927
  }
803
- this.applyAspectRatio(this.channel0 || urls[0]);
928
+ this.syncFrameConsumers(channels);
929
+ const aspectHint = this.channel0.startsWith("#") ? "" : this.channel0 || urls[0];
930
+ this.applyAspectRatio(aspectHint);
804
931
  this.syncSize();
805
932
  this.runtime.setSources(sources, channels);
806
933
  if (token !== this.rebuildToken || !this.runtime || this.runtime.isLost) {
@@ -893,6 +1020,7 @@ let SonicShader = class SonicShader extends LitElement {
893
1020
  mouse: this.mouseVec,
894
1021
  params,
895
1022
  });
1023
+ this.frameSeq++;
896
1024
  this.maybePublishOut(now, time, params);
897
1025
  void this.maybeExtract(now, time);
898
1026
  }
@@ -1171,8 +1299,8 @@ let SonicShader = class SonicShader extends LitElement {
1171
1299
  if (!rect)
1172
1300
  continue;
1173
1301
  // Copie : le buffer WebGL peut être réutilisé / invalidé ensuite
1174
- const rgba = new Uint8Array(rect.data);
1175
- const mean = meanRgba(rgba);
1302
+ const rgba = rgbaToUint8(rect.data);
1303
+ const mean = meanRgba(rect.data);
1176
1304
  const item = {
1177
1305
  id: roi.id || `${source}-${px.x}-${px.y}`,
1178
1306
  x: this.round3(rect.x / bufW),
@@ -1271,7 +1399,7 @@ let SonicShader = class SonicShader extends LitElement {
1271
1399
  item.score = this.round3(score);
1272
1400
  if (this.extractBitmaps) {
1273
1401
  const token = this.rebuildToken;
1274
- const url = await rgbaToBlobUrl(rect.data, rect.width, rect.height);
1402
+ const url = await rgbaToBlobUrl(rgbaToUint8(rect.data), rect.width, rect.height);
1275
1403
  if (token !== this.rebuildToken || !this.isConnected) {
1276
1404
  if (url)
1277
1405
  revokeMediaUrls([url]);
@@ -1520,11 +1648,29 @@ __decorate([
1520
1648
  property({ type: Number, attribute: "hover-speed" })
1521
1649
  ], SonicShader.prototype, "hoverSpeed", void 0);
1522
1650
  __decorate([
1523
- property({ type: Boolean, attribute: "release-offscreen" })
1651
+ property({
1652
+ attribute: "release-offscreen",
1653
+ converter: {
1654
+ fromAttribute: (value) => parseReleaseOffscreen(value),
1655
+ toAttribute: (value) => {
1656
+ if (value === "auto")
1657
+ return "auto";
1658
+ if (value === false)
1659
+ return "false";
1660
+ return "";
1661
+ },
1662
+ },
1663
+ })
1524
1664
  ], SonicShader.prototype, "releaseOffscreen", void 0);
1525
1665
  __decorate([
1526
1666
  property({ type: Number, attribute: "dpr-max" })
1527
1667
  ], SonicShader.prototype, "dprMax", void 0);
1668
+ __decorate([
1669
+ property({ attribute: "buffer-format" })
1670
+ ], SonicShader.prototype, "bufferFormat", void 0);
1671
+ __decorate([
1672
+ property({ attribute: "active-buffer-format", reflect: true })
1673
+ ], SonicShader.prototype, "activeBufferFormat", void 0);
1528
1674
  __decorate([
1529
1675
  property({ type: Number, attribute: "param0" })
1530
1676
  ], SonicShader.prototype, "param0", void 0);
@@ -1586,8 +1732,8 @@ SonicShader = __decorate([
1586
1732
  customElement(tagName)
1587
1733
  ], SonicShader);
1588
1734
  export { SonicShader };
1589
- export { parseChannelSource, ShaderToyRuntime } from "./gl-runtime";
1735
+ export { parseChannelSource, ShaderToyRuntime, shouldUploadElementFrame, resolveBufferGlFormat, resetBufferFormatWarnFlag } from "./gl-runtime";
1590
1736
  export { buildFragmentSource } from "./shadertoy-prelude";
1591
- export { toMediaUrl, cloneMediaRef, } from "@supersoniks/concorde/core/utils/mediaRef";
1592
- export { findPeaks, meanRgba, parseExtractPass, parseHoverParam, roiToPixels, ShaderCompileError, } from "./types";
1737
+ export { toMediaUrl, cloneMediaRef, isFrameSource, mediaElementKey, } from "@supersoniks/concorde/core/utils/mediaRef";
1738
+ export { channelsUseSelf, findPeaks, meanRgba, parseBufferFormat, parseExtractPass, parseHoverParam, parseReleaseOffscreen, roiToPixels, rgbaToUint8, shouldReleaseWhenOffscreen, ShaderCompileError, } from "./types";
1593
1739
  //# sourceMappingURL=shader.js.map