@photivra/engine 2.20.0 → 2.21.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.
Files changed (174) hide show
  1. package/CHANGELOG.md +178 -1
  2. package/CITATION.cff +1 -1
  3. package/README.md +7 -6
  4. package/SECURITY.md +1 -1
  5. package/THIRD_PARTY.md +7 -0
  6. package/dist/capture/dng-lens-correction-opcodes.d.ts +2 -2
  7. package/dist/capture/dng-lens-correction-opcodes.js +2 -2
  8. package/dist/capture/dng-lens-correction-opcodes.js.map +1 -1
  9. package/dist/capture/exposure-build-up-stage.d.ts +16 -0
  10. package/dist/capture/exposure-build-up-stage.js +4 -0
  11. package/dist/capture/exposure-build-up-stage.js.map +1 -0
  12. package/dist/capture/native-environment-lean.d.ts +2 -1
  13. package/dist/capture/native-environment-lean.js +41 -73
  14. package/dist/capture/native-environment-lean.js.map +1 -1
  15. package/dist/capture/native-environment-tabulated.js +4 -3
  16. package/dist/capture/native-environment-tabulated.js.map +1 -1
  17. package/dist/capture/native-raw.d.ts +3 -2
  18. package/dist/capture/native-raw.js +5 -4
  19. package/dist/capture/native-raw.js.map +1 -1
  20. package/dist/capture/sensor-raw-producer.d.ts +4 -1
  21. package/dist/capture/sensor-raw-producer.js +12 -3
  22. package/dist/capture/sensor-raw-producer.js.map +1 -1
  23. package/dist/core/version.d.ts +1 -1
  24. package/dist/core/version.js +1 -1
  25. package/dist/core/version.js.map +1 -1
  26. package/dist/equipment/generic-lens-catalogue.d.ts +3 -2
  27. package/dist/equipment/generic-lens-catalogue.js +18 -5
  28. package/dist/equipment/generic-lens-catalogue.js.map +1 -1
  29. package/dist/equipment/generic-tier-assets.d.ts +32 -0
  30. package/dist/equipment/generic-tier-assets.js +16 -11
  31. package/dist/equipment/generic-tier-assets.js.map +1 -1
  32. package/dist/equipment/sensor-profile-body.d.ts +78 -0
  33. package/dist/equipment/sensor-profile-body.js +77 -0
  34. package/dist/equipment/sensor-profile-body.js.map +1 -0
  35. package/dist/equipment/sensor-profiles.d.ts +8 -0
  36. package/dist/equipment/sensor-profiles.js +82 -0
  37. package/dist/equipment/sensor-profiles.js.map +1 -0
  38. package/dist/facade/catalogue-lens-signal.d.ts +2 -2
  39. package/dist/facade/catalogue-lens-signal.js +58 -71
  40. package/dist/facade/catalogue-lens-signal.js.map +1 -1
  41. package/dist/facade/chart-radiance-batch.js +2 -1
  42. package/dist/facade/chart-radiance-batch.js.map +1 -1
  43. package/dist/facade/defocus-image-space-provider.d.ts +7 -0
  44. package/dist/facade/defocus-image-space-provider.js +64 -76
  45. package/dist/facade/defocus-image-space-provider.js.map +1 -1
  46. package/dist/facade/display-view-gpu-session.js +2 -0
  47. package/dist/facade/display-view-gpu-session.js.map +1 -1
  48. package/dist/facade/display-view-gpu.d.ts +6 -1
  49. package/dist/facade/display-view-gpu.js.map +1 -1
  50. package/dist/facade/display-view-lens-signal.js +25 -23
  51. package/dist/facade/display-view-lens-signal.js.map +1 -1
  52. package/dist/facade/display-view.js +5 -23
  53. package/dist/facade/display-view.js.map +1 -1
  54. package/dist/facade/expected-signal-setup.d.ts +3 -1
  55. package/dist/facade/expected-signal-setup.js +1 -1
  56. package/dist/facade/expected-signal-setup.js.map +1 -1
  57. package/dist/facade/expected-signal.d.ts +47 -14
  58. package/dist/facade/expected-signal.js +117 -112
  59. package/dist/facade/expected-signal.js.map +1 -1
  60. package/dist/facade/exposure-build-up.d.ts +70 -0
  61. package/dist/facade/exposure-build-up.js +164 -0
  62. package/dist/facade/exposure-build-up.js.map +1 -0
  63. package/dist/facade/fast-methods.js +9 -1
  64. package/dist/facade/fast-methods.js.map +1 -1
  65. package/dist/facade/generic-lens-capture.d.ts +2 -2
  66. package/dist/facade/generic-lens-capture.js +2 -2
  67. package/dist/facade/generic-lens-capture.js.map +1 -1
  68. package/dist/facade/image-plane-enable.d.ts +7 -0
  69. package/dist/facade/image-plane-enable.js +17 -0
  70. package/dist/facade/image-plane-enable.js.map +1 -0
  71. package/dist/facade/image-plane-lattice-data.d.ts +6 -0
  72. package/dist/facade/image-plane-lattice-data.js +10 -0
  73. package/dist/facade/image-plane-lattice-data.js.map +1 -0
  74. package/dist/facade/image-plane-support.d.ts +33 -0
  75. package/dist/facade/image-plane-support.js +11 -0
  76. package/dist/facade/image-plane-support.js.map +1 -0
  77. package/dist/facade/image-plane.d.ts +36 -0
  78. package/dist/facade/image-plane.js +353 -0
  79. package/dist/facade/image-plane.js.map +1 -0
  80. package/dist/facade/mixed-illumination.d.ts +108 -0
  81. package/dist/facade/mixed-illumination.js +174 -0
  82. package/dist/facade/mixed-illumination.js.map +1 -0
  83. package/dist/facade/representative-light-sources.d.ts +72 -0
  84. package/dist/facade/representative-light-sources.js +124 -0
  85. package/dist/facade/representative-light-sources.js.map +1 -0
  86. package/dist/facade/scene-radiance.d.ts +129 -4
  87. package/dist/facade/scene-radiance.js +48 -13
  88. package/dist/facade/scene-radiance.js.map +1 -1
  89. package/dist/facade/simulate-capture.d.ts +39 -10
  90. package/dist/facade/simulate-capture.js +252 -92
  91. package/dist/facade/simulate-capture.js.map +1 -1
  92. package/dist/facade/simulate-display-view.js +14 -6
  93. package/dist/facade/simulate-display-view.js.map +1 -1
  94. package/dist/gpu/chart-composite-gpu.d.ts +13 -1
  95. package/dist/gpu/chart-composite-gpu.js +48 -9
  96. package/dist/gpu/chart-composite-gpu.js.map +1 -1
  97. package/dist/gpu/chart-radiance-gpu.js +4 -30
  98. package/dist/gpu/chart-radiance-gpu.js.map +1 -1
  99. package/dist/gpu/display-view-composite-material-module.d.ts +10 -4
  100. package/dist/gpu/display-view-composite-material-module.js +39 -13
  101. package/dist/gpu/display-view-composite-material-module.js.map +1 -1
  102. package/dist/gpu/display-view-image-material-module.d.ts +86 -0
  103. package/dist/gpu/display-view-image-material-module.js +339 -0
  104. package/dist/gpu/display-view-image-material-module.js.map +1 -0
  105. package/dist/gpu/display-view-image-quality.d.ts +45 -0
  106. package/dist/gpu/display-view-image-quality.js +380 -0
  107. package/dist/gpu/display-view-image-quality.js.map +1 -0
  108. package/dist/gpu/display-view-quality-gpu.d.ts +67 -1
  109. package/dist/gpu/display-view-quality-gpu.js +136 -205
  110. package/dist/gpu/display-view-quality-gpu.js.map +1 -1
  111. package/dist/gpu/display-view-speed-gpu.d.ts +51 -3
  112. package/dist/gpu/display-view-speed-gpu.js +131 -93
  113. package/dist/gpu/display-view-speed-gpu.js.map +1 -1
  114. package/dist/gpu/wgsl-display-view-quality-kernel.d.ts +29 -15
  115. package/dist/gpu/wgsl-display-view-quality-kernel.js +58 -36
  116. package/dist/gpu/wgsl-display-view-quality-kernel.js.map +1 -1
  117. package/dist/gpu/wgsl-display-view-speed-kernel.d.ts +21 -6
  118. package/dist/gpu/wgsl-display-view-speed-kernel.js +46 -11
  119. package/dist/gpu/wgsl-display-view-speed-kernel.js.map +1 -1
  120. package/dist/gpu/wgsl-exact-sum.d.ts +20 -0
  121. package/dist/gpu/wgsl-exact-sum.js +42 -0
  122. package/dist/gpu/wgsl-exact-sum.js.map +1 -0
  123. package/dist/index.d.ts +11 -3
  124. package/dist/index.js +7 -1
  125. package/dist/index.js.map +1 -1
  126. package/dist/motion/subject-motion.d.ts +66 -0
  127. package/dist/motion/subject-motion.js +52 -0
  128. package/dist/motion/subject-motion.js.map +1 -0
  129. package/dist/optics/generic-lens-lateral-color.d.ts +83 -0
  130. package/dist/optics/generic-lens-lateral-color.js +77 -0
  131. package/dist/optics/generic-lens-lateral-color.js.map +1 -0
  132. package/dist/optics/generic-lens-psf.js +54 -46
  133. package/dist/optics/generic-lens-psf.js.map +1 -1
  134. package/dist/optics/lens-psf-profile.d.ts +7 -0
  135. package/dist/optics/lens-psf-profile.js +2 -1
  136. package/dist/optics/lens-psf-profile.js.map +1 -1
  137. package/dist/output/developed-lens-corrections.d.ts +19 -5
  138. package/dist/output/developed-lens-corrections.js +28 -9
  139. package/dist/output/developed-lens-corrections.js.map +1 -1
  140. package/dist/output/generic-lens-corrections.d.ts +41 -5
  141. package/dist/output/generic-lens-corrections.js +52 -8
  142. package/dist/output/generic-lens-corrections.js.map +1 -1
  143. package/dist/output/print-plan.d.ts +41 -5
  144. package/dist/output/print-plan.js +59 -14
  145. package/dist/output/print-plan.js.map +1 -1
  146. package/dist/sensor/binomial-sample.d.ts +3 -0
  147. package/dist/sensor/binomial-sample.js +86 -0
  148. package/dist/sensor/binomial-sample.js.map +1 -0
  149. package/dist/sensor/sensor-characteristics.d.ts +10 -0
  150. package/dist/sensor/sensor-characteristics.js +20 -9
  151. package/dist/sensor/sensor-characteristics.js.map +1 -1
  152. package/docs/AGENT_GUIDE.md +1 -0
  153. package/docs/API_REFERENCE.md +98 -1
  154. package/docs/QUICK_START.md +125 -0
  155. package/docs/USAGE.md +92 -1
  156. package/docs/api/core-version.md +1 -1
  157. package/docs/api/equipment-generic-lens-catalogue.md +10 -5
  158. package/docs/api/equipment-sensor-profile-body.md +64 -0
  159. package/docs/api/equipment-sensor-profiles.md +86 -0
  160. package/docs/api/exports.json +207 -2
  161. package/docs/api/facade-exposure-build-up.md +105 -0
  162. package/docs/api/facade-fast-methods.md +9 -1
  163. package/docs/api/facade-image-plane-enable.md +16 -0
  164. package/docs/api/facade-mixed-illumination.md +67 -0
  165. package/docs/api/facade-representative-light-sources.md +131 -0
  166. package/docs/api/facade-scene-radiance.md +54 -3
  167. package/docs/api/facade-simulate-capture.md +26 -6
  168. package/docs/api/motion-subject-motion.md +23 -0
  169. package/docs/api/optics-generic-lens-lateral-color.md +79 -0
  170. package/docs/api/output-developed-lens-corrections.md +10 -1
  171. package/docs/api/output-generic-lens-corrections.md +40 -4
  172. package/docs/api/output-print-plan.md +35 -1
  173. package/llms.txt +2 -0
  174. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"defocus-image-space-provider.js","sourceRoot":"","sources":["../../src/facade/defocus-image-space-provider.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,gIAAgI;AAChI,4HAA4H;AAC5H,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,gCAAgC,EAAE,kCAAkC,EAAE,8BAA8B,EAAE,MAAM,wCAAwC,CAAC;AAE9J,OAAO,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,6BAA6B,EAA4B,MAAM,8BAA8B,CAAC;AAC9J,OAAO,EAAE,2BAA2B,EAAE,2BAA2B,EAAuC,MAAM,8BAA8B,CAAC;AAC7I,OAAO,EAAE,uCAAuC,EAAsC,MAAM,sCAAsC,CAAC;AACnI,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAA4C,MAAM,uCAAuC,CAAC;AAC7I,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,cAAc,EAAE,UAAU,EAA6B,MAAM,2BAA2B,CAAC;AAExI,OAAO,EAAE,yBAAyB,EAAE,6BAA6B,EAAyD,MAAM,4BAA4B,CAAC;AAE7J,qGAAqG;AACrG,MAAM,SAAS,GAAG,EAAE,CAAC;AACrB,MAAM,YAAY,GAAG,CAAC,CAAC;AACvB,MAAM,uBAAuB,GAAG,IAAI,CAAC;AA0BrC,0HAA0H;AAC1H,MAAM,UAAU,gCAAgC,CAAC,QAAmC;IAClF,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,wBAAwB,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,QAAQ,CAAC;IAC7G,0HAA0H;IAC1H,MAAM,EAAE,GAAG,2BAA2B,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC,oBAAoB,CAAC;IAC3F,MAAM,KAAK,GAAwB,WAAW,EAAE,OAAO,CAAC,eAAe,IAAI,aAAa,CAAC;IACzF,gJAAgJ;IAChJ,MAAM,QAAQ,GAAG,WAAW,EAAE,OAAO,CAAC,kBAAkB,KAAK,cAAc,CAAC;IAC5E,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,KAAK,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC;IAC/E,8IAA8I;IAC9I,MAAM,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,uCAAuC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClG,MAAM,YAAY,GAAG,CAAC,CAAS,EAAgD,EAAE,CAC/E,aAAa,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IACvH,8HAA8H;IAC9H,4GAA4G;IAC5G,IAAI,UAAU,GAAG,GAAG,EAAE,CAAC,GAAa,EAAE,CAAC;IACvC,MAAM,QAAQ,GAAG,CAAC,CAAsC,EAAE,CAAS,EAAuC,EAAE;QAC1G,IAAI,CAAC,KAAK,UAAU,EAAE,CAAC;YACrB,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,2BAA2B,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,qBAAqB,CAAC,EACzG,EAAE,GAAG,2BAA2B,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,qBAAqB,CAAC,EAAE,EAAE,GAAG,2BAA2B,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,qBAAqB,CAAC,CAAC;YACrK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;YAC3D,UAAU,GAAG,CAAC,CAAC;QACjB,CAAC;QACD,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAChJ,CAAC,CAAC;IACF,OAAO;QACL,aAAa;QACb,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;YAChB,MAAM,KAAK,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;YAClC,MAAM,EAAE,KAAK,EAAE,oBAAoB,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,qBAAqB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,EAAE,CAAC;YAC5I,IAAI,EAAU,EAAE,EAAU,EAAE,EAAU,CAAC;YACvC,IAAI,KAAK,KAAK,aAAa,EAAE,CAAC;gBAC5B,mHAAmH;gBACnH,MAAM,SAAS,GAAG,2BAA2B,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC;gBAClI,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC;oBAAE,MAAM,IAAI,yBAAyB,CAAC,qFAAqF,CAAC,CAAC;gBACnJ,EAAE,GAAG,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;gBAAC,EAAE,GAAG,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;gBAAC,EAAE,GAAG,EAAE,CAAC;YACxF,CAAC;iBAAM,CAAC;gBACN,MAAM,SAAS,GAAG,2BAA2B,CAAC,QAAQ,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;oBACnJ,4BAA4B,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC;gBACrG,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC;gBAAC,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC;gBAAC,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC;YACvD,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;YAClC,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1D,OAAO,EAAE,CAAC,EAAE,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,oBAAoB,EAAE,CAAC;QACvG,CAAC;QACD,aAAa,CAAC,IAAI,EAAE,CAAC;YACnB,IAAI,CAAC;gBACH,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBACnD,IAAI,KAA+B,CAAC;gBACpC,IAAI,KAAK,KAAK,aAAa,EAAE,CAAC;oBAC5B,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;wBAAE,OAAO,SAAS,CAAC;oBACjC,KAAK,GAAG,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvD,CAAC;;oBAAM,KAAK,GAAG,6BAA6B,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;gBACpF,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,mBAAmB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;gBACpF,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;YACxG,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAgCD,uHAAuH;AACvH,MAAM,UAAU,+BAA+B,CAAC,KAAqC;IACnF,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC;IAClG,MAAM,SAAS,GAAG,KAAK,CAAC,oBAAoB,GAAG,IAAI,CAAC;IACpD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,KAAK,CAAC,iBAAiB,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAU,EAAE,GAAG,MAAM,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjI,MAAM,MAAM,GAA+B,EAAE,CAAC;IAC9C,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtG,CAAC;IACD,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACvG,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAChE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/E,IAAI,CAAC,CAAC,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC;QAAE,MAAM,IAAI,yBAAyB,CAAC,gDAAgD,CAAC,CAAC;IACrH,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,EAAE,SAAS,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC;IAChC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACpG,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;IACvE,MAAM,WAAW,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9G,MAAM,YAAY,GAAG,CAAC,KAAK,IAAI,CAAC,WAAW,KAAK,SAAS,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/G,MAAM,KAAK,GAAG,KAAK,CAAC,kBAAkB,EAAE,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC;IACnE,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1G,MAAM,GAAG,GAAG,GAAW,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;IACtE,2GAA2G;IAC3G,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,CAAgB,EAAU,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC;IACjG,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,CAAgB,EAAU,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC;IACjG,8GAA8G;IAC9G,MAAM,KAAK,GAAG,IAAI,GAAG,EAA4B,CAAC;IAClD,MAAM,QAAQ,GAAG,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC;IACrE,4FAA4F;IAC5F,IAAI,QAAQ,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,GAAG,EAAE,UAAwC,CAAC;IAC5E,SAAS,IAAI,CAAC,CAAS,EAAE,IAAY;QACnC,IAAI,CAAC,KAAK,QAAQ,IAAI,IAAI,KAAK,QAAQ;YAAE,OAAO,UAAW,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAC/B,QAAQ,GAAG,CAAC,CAAC;QAAC,QAAQ,GAAG,IAAI,CAAC;QAAC,UAAU,GAAG,MAAM,CAAC;QACnD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,SAAS,MAAM,CAAC,CAAS,EAAE,IAAY;QACrC,MAAM,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpD,IAAI,MAAM,EAAE,CAAC;YAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAAC,OAAO,MAAM,CAAC;QAAC,CAAC;QACzE,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC,GAAG,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,GAAG,EAAE,CAAC,EAAE,UAAU,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,SAAS,GAAG,UAAU,CAAC;QAC/H,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YAClC,8FAA8F;YAC9F,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;YAC9F,MAAM,QAAQ,GAAG,UAAU,IAAI,gBAAgB,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACnF,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,UAAU,EAAE,EAAE,EAAE,EAAE,CAAC;gBACvC,MAAM,GAAG,GAAG,KAAK,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;gBACtC,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,SAAS,EAAE,EAAE,EAAE,EAAE,CAAC;oBACtC,MAAM,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,EAAE,EAAE,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;oBAC7F,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;wBAAE,MAAM,IAAI,yBAAyB,CAAC,4EAA4E,CAAC,CAAC;oBACrI,mFAAmF;oBACnF,MAAM,CAAC,GAAG,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC;oBAC5B,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;oBAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;oBAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;oBAC9E,IAAI,QAAQ;wBAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,UAAW,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;gBACxD,CAAC;YACH,CAAC;YACD,2EAA2E;YAC3E,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;YACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;gBAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;oBAAE,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC;YACnH,yHAAyH;YACzH,yHAAyH;YACzH,IAAI,QAAQ,IAAI,YAAY,EAAE,CAAC;gBAC7B,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACvC,IAAI,OAAO,CAAC,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC;oBAC1C,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;wBACpC,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;wBACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;4BAAE,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;gCAAE,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC;wBAC9E,OAAO,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAE,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;oBAC3H,CAAC,CAAC,CAAC;oBACH,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;wBAC9B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAiB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,IAAI,YAAY,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;wBACjG,KAAK,MAAM,KAAK,IAAI,QAAQ;4BAAE,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,GAAG,CAAC;gCAAE,MAAM,IAAI,yBAAyB,CAAC,oFAAoF,CAAC,CAAC;wBAChM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;4BACpC,IAAI,GAAG,GAAG,CAAC,CAAC;4BACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE;gCAAE,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAE,GAAG,WAAW,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,CAAC;4BACnF,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAE,CAAC;wBACzB,CAAC;wBACD,OAAO,GAAG,CAAC;oBACb,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;gBACjC,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;gBACvC,IAAI,QAAQ,EAAE,CAAC;oBACb,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;oBAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;wBAC9B,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC;wBACvB,IAAI,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;wBAC5B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;4BAAC,KAAK,GAAG,gBAAiB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;4BAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;wBAAC,CAAC;wBACtF,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAE,GAAG,KAAK,CAAC;oBAClC,CAAC;gBACH,CAAC;;oBAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;wBAAE,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC;gBAClG,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAE,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;gBACnI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE;oBAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAE,GAAG,GAAG,CAAC,CAAC,CAAE,CAAC;gBAC/E,OAAO,QAAQ,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACvB,IAAI,KAAK,CAAC,IAAI,GAAG,QAAQ;YAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAM,CAAC,CAAC;QACpE,IAAI,KAAK,CAAC,aAAa;YAAE,KAAK,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC;QAC9D,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,oIAAoI;IACpI,SAAS,KAAK,CAAC,IAAyC,EAAE,CAAS;QACjE,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC9C,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC1C,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,EAAE,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;QACrF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAE,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACrF,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,uBAAuB,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,uBAAuB;gBAAE,SAAS;YAC3H,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;YAC7B,IAAI,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,GAAG,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,IAAI,GAAG;gBAAE,OAAO,SAAS,CAAC;YACrE,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;QACjC,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,SAAS,OAAO,CAAC,GAAW,EAAE,CAAS,EAAE,EAAU;QACjD,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxB,IAAI,CAAC,KAAK,SAAS;YAAE,MAAM,IAAI,yBAAyB,CAAC,2FAA2F,CAAC,CAAC;QACtJ,MAAM,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,IAAI,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,IAAI,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;QAClF,IAAI,KAAK;YAAE,OAAO,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,CAAE,CAAC;IACxG,CAAC;IACD,8HAA8H;IAC9H,gEAAgE;IAChE,MAAM,aAAa,GAAG,IAAI,GAAG,EAAgF,CAAC;IAC9G,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC;IAC/E,oIAAoI;IACpI,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjG,SAAS,UAAU,CAAC,CAAS,EAAE,IAAY,EAAE,CAAS,EAAE,EAAU,EAAE,EAAU;QAC5E,MAAM,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;QAC3B,IAAI,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC;YACzB,MAAM,OAAO,GAAG,6BAA6B,CAAC,EAAE,MAAM,EAAE,KAAM,EAAE,aAAa,EAAE,aAAa,EAAE,yBAAyB,GAAG,iBAAiB,EAAE,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1M,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;oBAChC,MAAM,IAAI,GAAG,KAAK,GAAG,MAAM,EAAE,MAAM,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;oBACrH,MAAM,QAAQ,GAAG,UAAU,IAAI,gBAAgB,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;oBAClH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBAChC,MAAM,GAAG,GAAG,KAAK,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;wBACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;4BAC/B,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;4BACxB,yHAAyH;4BACzH,+DAA+D;4BAC/D,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC;gCAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gCAAC,SAAS;4BAAC,CAAC;4BACpH,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;4BAC9D,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;gCAAE,MAAM,IAAI,yBAAyB,CAAC,4EAA4E,CAAC,CAAC;4BACrI,MAAM,CAAC,GAAG,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC;4BAC5B,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;4BAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;4BAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;4BAC9E,IAAI,QAAQ;gCAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,UAAW,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;wBACxD,CAAC;oBACH,CAAC;oBACD,OAAO,CAAC,IAAY,EAAgB,EAAE;wBACpC,MAAM,EAAE,GAAG,aAAa,CAAC,IAAI,CAAE,EAAE,OAAO,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;wBAClE,IAAI,QAAQ,EAAE,CAAC;4BACb,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;4BAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;gCAC9B,IAAI,MAAM,CAAC,CAAC,CAAC;oCAAE,SAAS;gCACxB,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC;gCACvB,IAAI,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gCAC5B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oCAAC,KAAK,GAAG,gBAAiB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oCAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;gCAAC,CAAC;gCACtF,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAE,GAAG,KAAK,CAAC;4BAClC,CAAC;wBACH,CAAC;;4BAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;gCAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;oCAAE,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC;wBAClH,OAAO,OAAO,CAAC;oBACjB,CAAC,CAAC;gBACJ,CAAC,EAAE,CAAC,CAAC;YACP,KAAK,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;YACpC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC9B,IAAI,aAAa,CAAC,IAAI,GAAG,iBAAiB;gBAAE,aAAa,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAM,CAAC,CAAC;QACvG,CAAC;QACD,iHAAiH;QACjH,MAAM,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,EAAE,GAAG,OAAO,GAAG,EAAE,CAAC;QAC5F,IAAI,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC;YACzB,wHAAwH;YACxH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;gBAAC,MAAM,GAAG,GAAG,KAAK,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;gBAAC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;oBAAE,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC;YAAC,CAAC;YACrN,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAE,CAAC;IAClF,CAAC;IACD,SAAS,SAAS,CAAC,IAAyC,EAAE,IAAY,EAAE,EAAU;QACpF,MAAM,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAClE,IAAI,GAAG,KAAK,SAAS;YAAE,MAAM,IAAI,yBAAyB,CAAC,2FAA2F,CAAC,CAAC;QACxJ,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7B,CAAC;IACD,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC;IAC3C,MAAM,gBAAgB,GAAG,CAAC,OAAiD,EAAiC,EAAE;QAC5G,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,GAAI,OAAO,CAAC,MAA+E,CAAC,2BAA2B,CAAC;QAC1K,OAAO,EAAE,GAAG,MAAM,EAAE,qDAAqD,EAAE,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,4BAA4B,EAAE,OAAO,CAAC,oBAAoB,CAAC,EAAE,CAAC;IAC5L,CAAC,CAAC;IACF,mIAAmI;IACnI,oIAAoI;IACpI,wCAAwC;IACxC,IAAI,gCAAgC,CAAC,YAAY,CAAC,EAAE,CAAC;QACnD,kCAAkC,CAAC,gBAAgB,CAAC,CAAC;QACrD,6HAA6H;QAC7H,MAAM,KAAK,GAAa,EAAE,EAAE,SAAS,GAAG,IAAI,GAAG,EAAkB,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,GAAG,EAAE,GAAG,EAAE,CAAC;QACzG,8BAA8B,CAAC,gBAAgB,EAAE;YAC/C,SAAS,EAAE,KAAK;YAChB,cAAc,CAAC,CAAC,EAAE,IAAI;gBACpB,MAAM,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;gBAC3F,IAAI,GAAG,KAAK,SAAS;oBAAE,OAAO,SAAS,CAAC;gBACxC,IAAI,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC7B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBAAC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;oBAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;gBAAC,CAAC;gBAC1F,OAAO,KAAK,GAAG,WAAW,GAAG,GAAG,CAAC;YACnC,CAAC;YACD,aAAa,CAAC,GAAG,EAAE,EAAE;gBACnB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,WAAW,CAAC,CAAC;gBAC5C,OAAO,OAAO,CAAC,GAAG,GAAG,KAAK,GAAG,WAAW,EAAE,KAAK,CAAC,KAAK,CAAE,EAAE,EAAE,CAAC,CAAC;YAC/D,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IACD,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU;QAC7F,gBAAgB;QAChB,wBAAwB;YACtB,MAAM,IAAI,yBAAyB,CAAC,8DAA8D,CAAC,CAAC;QACtG,CAAC;KACF,CAAC;AACJ,CAAC;AAwBD,6IAA6I;AAC7I,MAAM,UAAU,8BAA8B,CAAC,KAGC;IAC9C,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,gBAAgB,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IAC9I,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,GAA+B,EAAE,CAAC;IACrD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;QAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,IAAI,EAAE,CAAC,CAAC;IAC9J,IAAI,QAAQ,GAAkB,IAAI,CAAC;IACnC,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;QAC3B,QAAQ,GAAG,CAAC,CAAC;QACb,MAAM,KAAK,GAAG,KAAK,CAAC,wBAAwB,CAAC;QAC7C,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,EAAE,CAAC;YAC/C,qHAAqH;YACrH,MAAM,IAAI,GAAG,2BAA2B,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,EAAE,qBAAqB,CAAC,CAAC;YAC5J,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;gBAC9D,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;gBAC5E,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,UAAU,GAAkB,IAAI,CAAC;IACrC,IAAI,WAAW,IAAI,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAClE,UAAU,GAAG,CAAC,CAAC;QACf,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,MAAM,MAAM,GAAG,mBAAmB,CAAC,WAAW,EAAE,qBAAqB,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YAC/G,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IACD,IAAI,UAAU,GAAkB,IAAI,CAAC;IACrC,IAAI,WAAW,IAAI,WAAW,CAAC,OAAO,CAAC,eAAe,KAAK,aAAa,EAAE,CAAC;QACzE,UAAU,GAAG,CAAC,CAAC;QACf,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC1C,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;IACD,OAAO,EAAE,iBAAiB,EAAE,CAAC,EAAE,kCAAkC,EAAE,QAAQ,EAAE,oCAAoC,EAAE,UAAU,EAAE,oCAAoC,EAAE,UAAU,EAAE,CAAC;AACpL,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * `simulateCapture`'s `lens.defocus` out of focus together with a lens field mapping (`lens.projection`,\n * `lens.distortion`), `lens.vignetting` or camera rotation (#548): the geometric defocus disc applied in image space,\n * on the site lattice of the sensor, instead of on the scene plane.\n *\n * Why the object-space path does not apply. `createDiffractedPlanarProvider` convolves the scene radiance on the plane\n * lattice that the sites see through one linear map (a still, rectilinear, distortion-free camera with the same\n * radiance-to-irradiance factor everywhere). A projection, a distortion or a rotation makes the map from sensor points\n * to plane points non-linear (or time-dependent), and vignetting makes the factor vary over the field, so the disc on\n * the plane is no longer the disc on the sensor.\n *\n * The image-space model. The environment PSF quadrature (`calculateSensorPsfIrradianceQuadrature`, the per-tap path\n * `lens.diffraction` falls back to) defines a sensor-plane PSF K as\n * E(q, λ, t) = Σ_k K(k)·F(s_k)·C·L(D_t(s_k), λ),\n * with s_k = q + k·p the tap source points on the sensor (p the site pitch), D_t the scene ray of a sensor point at\n * time t (inverse distortion, the declared projection, the camera rotation at t), F = T·A the field factor (vignetting\n * throughput T, applied once before the PSF spreads the light, and the distortion area factor A = 1/det J) and C the\n * paraxial radiance-to-irradiance factor π/(4·N_w²), the same everywhere. With K the defocus disc sampled on the site\n * lattice (`createDefocusDiscSiteKernel`), every source point of a site-centre query is another lattice point, so\n * E(q, λ, t) = C·G_t(q, λ), G_t = K ⊛ (F·L∘D_t) sampled on the lattice,\n * the same sum in a different floating-point order. This provider computes G_t once per spectral node and time on the\n * sensor lattice (in row bands, as the diffraction provider does) and answers the query of lattice point q at time t with\n * G_t(q, λ) / F(q); the environment multiplies by F(q)·C again, so each site gets C·G_t(q, λ). For the still,\n * rectilinear, distortion-free camera without vignetting it is the object-space convolution (F = 1 and D linear).\n *\n * The lattices. As in the diffraction provider, a pixel aperture or anti-aliasing spots add query offsets; each distinct\n * fractional offset gets its own shifted lattice of sensor points, and every tap of a query on one lattice is on the same\n * lattice. A query is located on its lattice by mapping its scene ray back to the sensor (camera rotation inverted at the\n * request's time, the forward projection, the forward distortion), within 1e-4 site; a query that lands on no lattice point\n * is refused rather than approximated.\n *\n * Time. With camera rotation each environment temporal midpoint is a still camera, so the disc is applied to that\n * instant's image in that instant's frame: one G_t per distinct request time, cached per band. Without rotation the image\n * does not depend on time and one G is kept. The facade refuses rotation with a rolling shutter (each row's instants differ).\n *\n * What is approximate is the disc itself (`lens.defocus` labels it; the facade records the field-variation bounds of\n * each combination), not this evaluation of it.\n */\n\n// #564: a defocus kernel above 64 sites (`largeKernel`) takes the run lattice of large-defocus-lattice.ts instead of the bands:\n// the samples F·L at the same lattice points, convolved by runs in fixed tiles, then divided by each queried point's own F.\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { hypot3 } from \"../core/portable-math.js\";\nimport { isInternalSceneRadianceEvaluator, markInternalSceneRadianceEvaluator, registerInternalRadianceAccess } from \"../core/internal-radiance-evaluator.js\";\nimport type { SceneRadianceEvaluationRequest, SceneRadianceEvaluationResult } from \"../schema/scene-radiance.js\";\nimport { insideRadialImageCircle, lensProjectionDirectionValue, lensProjectionImagePointValue, type LensProjectionModel } from \"../camera/lens-projection.js\";\nimport { applyPhysicalCameraRotation, resolveProjectionDistanceMm, type CameraAngularVelocityRadPerSec } from \"../motion/camera-rotation.js\";\nimport { prepareIlluminationVignettingThroughput, type IlluminationVignettingProfile } from \"../optics/illumination-vignetting.js\";\nimport { distortedImagePoint, undistortedImagePoint, type PreparedEnvironmentLensFieldMapping } from \"../optics/sensor-environment-query.js\";\nimport { checkedSiteKernel, createZonedGather, gatherInterior, kernelTaps, type SiteKernelFieldZones } from \"./diffraction-provider.js\";\nimport type { PlanarSceneRadianceProvider } from \"./scene-radiance.js\";\nimport { LARGE_DEFOCUS_CACHE_BYTES, createLargeDefocusNodeLattice, type LargeDefocusKernel, type LargeDefocusNodeLattice } from \"./large-defocus-lattice.js\";\n\n/** Rows of native sites per band; bands kept per time. Banding changes memory only, never values. */\nconst BAND_ROWS = 32;\nconst CACHED_BANDS = 2;\nconst LATTICE_TOLERANCE_SITES = 1e-4;\n\n/** The camera geometry the environment uses for each site query (the same options as the site inputs). */\nexport interface DefocusImageSpaceGeometry {\n focalLengthMm: number;\n focusDistanceM: number;\n angularVelocityRadPerSec: CameraAngularVelocityRadPerSec;\n /** The site inputs' `lensFieldMapping`, prepared; omitted for the ideal rectilinear, distortion-free mapping. */\n lensMapping?: PreparedEnvironmentLensFieldMapping;\n /** The site inputs' radial-illumination-vignetting profile; omitted for unity field throughput. */\n vignetting?: IlluminationVignettingProfile;\n}\n\n/** Internal: the scene ray and field factor of sensor points, and the sensor point of a scene ray, for one geometry. */\nexport interface PreparedDefocusImageSpaceGeometry {\n /**\n * The unit look direction (toward the scene, reference camera axes at exposure start) of native sensor point (x, y) mm\n * (+X right, +Y down) at time t, and its field factor F = T·A (vignetting throughput × distortion area factor).\n */\n lookOf(xMm: number, yMm: number, timeSeconds: number): { x: number; y: number; z: number; factor: number };\n /** The native sensor point (mm, +Y down) whose scene ray at time t is the look direction; undefined outside the mapping. */\n sensorPointOf(look: { x: number; y: number; z: number }, timeSeconds: number): { x: number; y: number } | undefined;\n /** True with camera rotation: the ray of a sensor point depends on time. */\n timeDependent: boolean;\n}\n\n/** Internal: prepares {@link PreparedDefocusImageSpaceGeometry} with the environment's own conventions and arithmetic. */\nexport function prepareDefocusImageSpaceGeometry(geometry: DefocusImageSpaceGeometry): PreparedDefocusImageSpaceGeometry {\n const { focalLengthMm, focusDistanceM, angularVelocityRadPerSec: omega, lensMapping, vignetting } = geometry;\n // The projection scale: the thin-lens image distance at the finite focus, for every projection model (the environment's).\n const pd = resolveProjectionDistanceMm(focalLengthMm, focusDistanceM).projectionDistanceMm;\n const model: LensProjectionModel = lensMapping?.mapping.projectionModel ?? \"rectilinear\";\n // #569: with \"backward-ray\" (catalogue fisheyes), a point outside the image circle looks straight back, as the environment's mapped query does.\n const backward = lensMapping?.mapping.outsideImageCircle === \"backward-ray\";\n const timeDependent = omega.pitch !== 0 || omega.yaw !== 0 || omega.roll !== 0;\n // calculateIlluminationVignetting's throughput with the profile validated once (#563: the same numbers, without a result envelope per point).\n const throughputAt = vignetting ? prepareIlluminationVignettingThroughput(vignetting) : undefined;\n const displacement = (t: number): { pitch: number; yaw: number; roll: number } =>\n timeDependent ? { pitch: omega.pitch * t, yaw: omega.yaw * t, roll: omega.roll * t } : { pitch: 0, yaw: 0, roll: 0 };\n // The reference-to-camera rotation at the last time asked, as a matrix (its columns: the rotated basis vectors), so a lattice\n // lookup costs no trigonometry; the rotation is linear, so this equals rotating the vector, up to rounding.\n let matrixTime = NaN, m: number[] = [];\n const toCamera = (v: { x: number; y: number; z: number }, t: number): { x: number; y: number; z: number } => {\n if (t !== matrixTime) {\n const d = displacement(t), ex = applyPhysicalCameraRotation({ x: 1, y: 0, z: 0 }, d, \"reference-to-camera\"),\n ey = applyPhysicalCameraRotation({ x: 0, y: 1, z: 0 }, d, \"reference-to-camera\"), ez = applyPhysicalCameraRotation({ x: 0, y: 0, z: 1 }, d, \"reference-to-camera\");\n m = [ex.x, ey.x, ez.x, ex.y, ey.y, ez.y, ex.z, ey.z, ez.z];\n matrixTime = t;\n }\n return { x: m[0]! * v.x + m[1]! * v.y + m[2]! * v.z, y: m[3]! * v.x + m[4]! * v.y + m[5]! * v.z, z: m[6]! * v.x + m[7]! * v.y + m[8]! * v.z };\n };\n return {\n timeDependent,\n lookOf(xMm, yMm, t): { x: number; y: number; z: number; factor: number } {\n const image = { x: xMm, y: -yMm };\n const { ideal, distortionAreaFactor } = lensMapping ? undistortedImagePoint(lensMapping, image) : { ideal: image, distortionAreaFactor: 1 };\n let lx: number, ly: number, lz: number;\n if (model === \"rectilinear\") {\n // calculateInverseCameraRotationImageMapping: the captured ray (x/pd, y/pd, 1) in reference axes, projected at pd.\n const reference = applyPhysicalCameraRotation({ x: ideal.x / pd, y: ideal.y / pd, z: 1 }, displacement(t), \"camera-to-reference\");\n if (!(reference.z > 0)) throw new InvalidConfigurationError(\"lens.defocus: a lattice point's ray points to or behind the reference camera plane.\");\n lx = pd * (reference.x / reference.z); ly = pd * (reference.y / reference.z); lz = pd;\n } else {\n const reference = applyPhysicalCameraRotation(backward && !insideRadialImageCircle(model, pd, Math.hypot(ideal.x, ideal.y)) ? { x: 0, y: 0, z: -1 } :\n lensProjectionDirectionValue(model, pd, ideal.x, ideal.y), displacement(t), \"camera-to-reference\");\n lx = reference.x; ly = reference.y; lz = reference.z;\n }\n const length = hypot3(lx, ly, lz);\n const throughput = throughputAt ? throughputAt(image) : 1;\n return { x: lx / length, y: ly / length, z: lz / length, factor: throughput * distortionAreaFactor };\n },\n sensorPointOf(look, t): { x: number; y: number } | undefined {\n try {\n const c = timeDependent ? toCamera(look, t) : look;\n let ideal: { x: number; y: number };\n if (model === \"rectilinear\") {\n if (!(c.z > 0)) return undefined;\n ideal = { x: pd * (c.x / c.z), y: pd * (c.y / c.z) };\n } else ideal = lensProjectionImagePointValue(model, pd, c.x, c.y, c.z).imagePointMm;\n const image = lensMapping ? distortedImagePoint(lensMapping, ideal).pointMm : ideal;\n return Number.isFinite(image.x) && Number.isFinite(image.y) ? { x: image.x, y: -image.y } : undefined;\n } catch {\n return undefined;\n }\n }\n };\n}\n\nexport interface DefocusImageSpaceProviderInput {\n base: PlanarSceneRadianceProvider;\n geometry: PreparedDefocusImageSpaceGeometry;\n /** Each spectral node's kernel on the site lattice, (2·kernelRadius + 1)² taps, row-major (the disc, or diffraction ⊛ disc). */\n siteKernels: (wavelengthNm: number) => Float64Array;\n wavelengthsNm: readonly number[];\n kernelRadius: number;\n nativeWidth: number;\n nativeHeight: number;\n sitePitchMicrometers: number;\n /** Planar geometry of the base provider (plane distance and frame-unit scale), to find the plane point of a ray as it does. */\n distanceM: number;\n metresPerFrameUnit: number;\n /** Offsets of the query points from the site centres, in sites (+x right, +y down). Default: one zero offset. */\n queryOffsetsSites?: readonly { x: number; y: number }[];\n /** Region renders: the native sites that will be queried. Values are bit-identical to the whole render's. Default: the whole raster. */\n window?: { x: number; y: number; width: number; height: number };\n /** Most distinct request times kept per band (the temporal sample count). Default 1. */\n timesPerBand?: number;\n /** Called with the duration in ms of each band convolution (diagnostics only). */\n onConvolution?: (milliseconds: number) => void;\n /**\n * #564: a defocus kernel above the direct radius, convolved by runs in fixed tiles (`large-defocus-lattice.ts`), with each\n * node's diffraction kernel after it; used instead of `siteKernels` (`kernelRadius` is then unused).\n */\n largeKernel?: LargeDefocusKernel;\n /** #553: a field-varying kernel by zones (the cat's eye of lens.defocus), gathered instead of `siteKernels`, the same at every node. */\n fieldZones?: SiteKernelFieldZones;\n}\n\n/** Internal (not exported from the package): the base provider with the defocus disc applied in image space (#548). */\nexport function createDefocusImageSpaceProvider(input: DefocusImageSpaceProviderInput): PlanarSceneRadianceProvider {\n const { base, geometry, wavelengthsNm, nativeWidth: W, nativeHeight: H, kernelRadius: R } = input;\n const mmPerSite = input.sitePitchMicrometers / 1000;\n const index = new Map(wavelengthsNm.map((nm, i) => [nm, i]));\n const offsets = input.queryOffsetsSites ?? [{ x: 0, y: 0 }];\n const fraction = (value: number): number => { const f = value - Math.floor(value); return f > 1 - 1e-6 ? 0 : f < 1e-6 ? 0 : f; };\n const shifts: { x: number; y: number }[] = [];\n for (const o of offsets) {\n const f = { x: fraction(o.x), y: fraction(o.y) };\n if (!shifts.some((s) => Math.abs(s.x - f.x) <= 1e-6 && Math.abs(s.y - f.y) <= 1e-6)) shifts.push(f);\n }\n const M = Math.max(0, ...offsets.map((o) => Math.ceil(Math.max(Math.abs(o.x), Math.abs(o.y)) - 1e-6)));\n const LW = W + 2 * M, LH = H + 2 * M;\n const win = input.window ?? { x: 0, y: 0, width: W, height: H };\n const lx0 = Math.max(0, win.x), lx1 = Math.min(LW, win.x + win.width + 2 * M);\n const ly0 = Math.max(0, win.y), ly1 = Math.min(LH, win.y + win.height + 2 * M);\n if (!(lx0 < lx1 && ly0 < ly1)) throw new InvalidConfigurationError(\"Defocus window must overlap the native raster.\");\n const NW = lx1 - lx0, gridWidth = NW + 2 * R;\n const large = input.largeKernel;\n const kernels = large ? [] : wavelengthsNm.map((nm) => checkedSiteKernel(input.siteKernels(nm), R));\n const taps = kernels.map((kernel) => kernelTaps(kernel, R, gridWidth));\n const zonedGather = input.fieldZones ? createZonedGather(input.fieldZones, R, gridWidth, W, H, M) : undefined;\n const sharedKernel = !large && (zonedGather !== undefined || kernels.every((kernel) => kernel === kernels[0]));\n const scale = input.metresPerFrameUnit, distance = input.distanceM;\n const materialAt = base.chartMaterialAt?.bind(base), materialRadiance = base.materialRadiance?.bind(base);\n const now = (): number => globalThis.performance?.now() ?? Date.now();\n // Lattice point (li, lj) of shift s, as a native sensor point in mm (+Y down): site centre plus the shift.\n const xMmOf = (li: number, s: { x: number }): number => (li - M + 0.5 + s.x - W / 2) * mmPerSite;\n const yMmOf = (lj: number, s: { y: number }): number => (lj - M + 0.5 + s.y - H / 2) * mmPerSite;\n // Bands per time (LRU over (time, band)): values[shift][node] holds G_t / F at the band's own lattice points.\n const cache = new Map<string, Float64Array[][]>();\n const capacity = CACHED_BANDS * Math.max(1, input.timesPerBand ?? 1);\n // The last band read, so consecutive queries of one band skip the cache key (most queries).\n let lastBand = -1, lastTime = NaN, lastValues: Float64Array[][] | undefined;\n function band(b: number, time: number): Float64Array[][] {\n if (b === lastBand && time === lastTime) return lastValues!;\n const values = bandOf(b, time);\n lastBand = b; lastTime = time; lastValues = values;\n return values;\n }\n function bandOf(b: number, time: number): Float64Array[][] {\n const key = time + \":\" + b, cached = cache.get(key);\n if (cached) { cache.delete(key); cache.set(key, cached); return cached; }\n const started = input.onConvolution ? now() : 0;\n const y0 = ly0 + b * BAND_ROWS, rows = Math.min(BAND_ROWS, ly1 - y0), gridHeight = rows + 2 * R, size = gridWidth * gridHeight;\n const values = shifts.map((shift) => {\n // Each grid point's field factor and plane point (or material), shared by the spectral nodes.\n const factor = new Float64Array(size), u = new Float64Array(size), v = new Float64Array(size);\n const material = materialAt && materialRadiance ? new Int32Array(size) : undefined;\n for (let gy = 0; gy < gridHeight; gy++) {\n const yMm = yMmOf(y0 + gy - R, shift);\n for (let gx = 0; gx < gridWidth; gx++) {\n const k = gy * gridWidth + gx, look = geometry.lookOf(xMmOf(lx0 + gx - R, shift), yMm, time);\n if (!(look.z > 0)) throw new InvalidConfigurationError(\"lens.defocus: a lattice point's ray does not point toward the scene plane.\");\n // The base provider's own plane-point arithmetic for the outgoing direction −look.\n const t = distance / look.z;\n factor[k] = look.factor; u[k] = look.x * t / scale; v[k] = look.y * t / scale;\n if (material) material[k] = materialAt!(u[k]!, v[k]!);\n }\n }\n // The band's own lattice points' factors, to answer each query with G / F.\n const own = new Float64Array(rows * NW);\n for (let y = 0; y < rows; y++) for (let x = 0; x < NW; x++) own[y * NW + x] = factor[(y + R) * gridWidth + x + R]!;\n // One kernel for every node (the disc without diffraction) and fewer materials than nodes: the convolution is linear, so\n // G_λ = Σ_m L_m(λ)·(K ⊛ F·[material = m]); one convolution per material instead of one per node, the same sum regrouped.\n if (material && sharedKernel) {\n const present = [...new Set(material)];\n if (present.length < wavelengthsNm.length) {\n const perMaterial = present.map((m) => {\n const samples = new Float64Array(size);\n for (let k = 0; k < size; k++) if (material[k] === m) samples[k] = factor[k]!;\n return zonedGather ? zonedGather(samples, lx0, y0, NW, rows) : gatherInterior(samples, taps[0]!, gridWidth, NW, rows, R);\n });\n return wavelengthsNm.map((nm) => {\n const radiance = present.map((m) => materialRadiance!(m, nm)), out = new Float64Array(rows * NW);\n for (const value of radiance) if (!(value >= 0 && value <= 2 ** 100)) throw new InvalidConfigurationError(\"Irradiance samples must be finite, non-negative and within the declared magnitude.\");\n for (let k = 0; k < out.length; k++) {\n let sum = 0;\n for (let i = 0; i < present.length; i++) sum += radiance[i]! * perMaterial[i]![k]!;\n out[k] = sum / own[k]!;\n }\n return out;\n });\n }\n }\n return wavelengthsNm.map((nm, w) => {\n const samples = new Float64Array(size);\n if (material) {\n const radiance = new Map<number, number>();\n for (let k = 0; k < size; k++) {\n const m = material[k]!;\n let value = radiance.get(m);\n if (value === undefined) { value = materialRadiance!(m, nm); radiance.set(m, value); }\n samples[k] = factor[k]! * value;\n }\n } else for (let k = 0; k < size; k++) samples[k] = factor[k]! * base.radianceAt(u[k]!, v[k]!, nm);\n const gathered = zonedGather ? zonedGather(samples, lx0, y0, NW, rows) : gatherInterior(samples, taps[w]!, gridWidth, NW, rows, R);\n for (let k = 0; k < gathered.length; k++) gathered[k] = gathered[k]! / own[k]!;\n return gathered;\n });\n });\n cache.set(key, values);\n if (cache.size > capacity) cache.delete(cache.keys().next().value!);\n if (input.onConvolution) input.onConvolution(now() - started);\n return values;\n }\n /** The lattice key ((shift·LH + lj)·LW + li) of a look direction at time t, or undefined off the lattices or outside the window. */\n function keyOf(look: { x: number; y: number; z: number }, t: number): number | undefined {\n const point = geometry.sensorPointOf(look, t);\n if (point === undefined) return undefined;\n const fi = point.x / mmPerSite + W / 2 - 0.5, fj = point.y / mmPerSite + H / 2 - 0.5;\n for (let s = 0; s < shifts.length; s++) {\n const shift = shifts[s]!, i = Math.round(fi - shift.x), j = Math.round(fj - shift.y);\n if (Math.abs(fi - shift.x - i) > LATTICE_TOLERANCE_SITES || Math.abs(fj - shift.y - j) > LATTICE_TOLERANCE_SITES) continue;\n const li = i + M, lj = j + M;\n if (li < lx0 || lj < ly0 || li >= lx1 || lj >= ly1) return undefined;\n return (s * LH + lj) * LW + li;\n }\n return undefined;\n }\n function valueOf(key: number, t: number, nm: number): number {\n const w = index.get(nm);\n if (w === undefined) throw new InvalidConfigurationError(\"Defocus query is off the sensor site lattice; the image-space convolution does not apply.\");\n const li = key % LW, rest = (key - li) / LW, lj = rest % LH, s = (rest - lj) / LH;\n if (large) return largeValue(s, t, w, li, lj);\n return band(Math.floor((lj - ly0) / BAND_ROWS), t)[s]![w]![((lj - ly0) % BAND_ROWS) * NW + li - lx0]!;\n }\n // #564: one run lattice per (time, shift) of the samples F·L at the lattice points, and the own field factors F by tile, so a\n // query is answered with (K ⊛ D ⊛ F·L) / F as on the band path.\n const largeLattices = new Map<string, { lattice: LargeDefocusNodeLattice; own: Map<number, Float64Array> }>();\n const largeLatticeCount = shifts.length * Math.max(1, input.timesPerBand ?? 1);\n // Lattice points at most `reach` beyond the lattice feed queried values: the defocus kernel's radius plus the diffraction kernel's.\n const reach = large ? large.runs.radius + (large.diffraction ? large.diffraction.radius : 0) : 0;\n function largeValue(s: number, time: number, w: number, li: number, lj: number): number {\n const key = time + \":\" + s;\n let entry = largeLattices.get(key);\n if (!entry) {\n const shift = shifts[s]!;\n const lattice = createLargeDefocusNodeLattice({ kernel: large!, wavelengthsNm, capacityBytes: LARGE_DEFOCUS_CACHE_BYTES / largeLatticeCount, ...(input.onConvolution ? { onTile: input.onConvolution } : {}),\n source: (x0, y0, width, height) => {\n const size = width * height, factor = new Float64Array(size), u = new Float64Array(size), v = new Float64Array(size);\n const material = materialAt && materialRadiance ? new Int32Array(size) : undefined, beyond = new Uint8Array(size);\n for (let y = 0; y < height; y++) {\n const yMm = yMmOf(y0 + y, shift);\n for (let x = 0; x < width; x++) {\n const k = y * width + x;\n // A fixed tile's source reaches past the lattice: points beyond its reach feed no queried value, so they are 0 and never\n // mapped (the lens profiles are checked only up to the reach).\n if (x0 + x < -reach || x0 + x >= LW + reach || y0 + y < -reach || y0 + y >= LH + reach) { beyond[k] = 1; continue; }\n const look = geometry.lookOf(xMmOf(x0 + x, shift), yMm, time);\n if (!(look.z > 0)) throw new InvalidConfigurationError(\"lens.defocus: a lattice point's ray does not point toward the scene plane.\");\n const t = distance / look.z;\n factor[k] = look.factor; u[k] = look.x * t / scale; v[k] = look.y * t / scale;\n if (material) material[k] = materialAt!(u[k]!, v[k]!);\n }\n }\n return (node: number): Float64Array => {\n const nm = wavelengthsNm[node]!, samples = new Float64Array(size);\n if (material) {\n const radiance = new Map<number, number>();\n for (let k = 0; k < size; k++) {\n if (beyond[k]) continue;\n const m = material[k]!;\n let value = radiance.get(m);\n if (value === undefined) { value = materialRadiance!(m, nm); radiance.set(m, value); }\n samples[k] = factor[k]! * value;\n }\n } else for (let k = 0; k < size; k++) if (!beyond[k]) samples[k] = factor[k]! * base.radianceAt(u[k]!, v[k]!, nm);\n return samples;\n };\n } });\n entry = { lattice, own: new Map() };\n largeLattices.set(key, entry);\n if (largeLattices.size > largeLatticeCount) largeLattices.delete(largeLattices.keys().next().value!);\n }\n // The own factor of the lattice point, by 64-point tiles (kept for the request: 8 bytes per lattice point read).\n const T = 64, tx = Math.floor(li / T), ty = Math.floor(lj / T), tileKey = ty * 1048576 + tx;\n let own = entry.own.get(tileKey);\n if (!own) {\n own = new Float64Array(T * T);\n const shift = shifts[s]!;\n // Only the lattice's own points are queried; the rest of the tile is never read (and may lie beyond the lens profiles).\n for (let y = 0; y < T && ty * T + y < LH; y++) { const yMm = yMmOf(ty * T + y, shift); for (let x = 0; x < T && tx * T + x < LW; x++) own[y * T + x] = geometry.lookOf(xMmOf(tx * T + x, shift), yMm, time).factor; }\n entry.own.set(tileKey, own);\n }\n return entry.lattice.valueAt(w, li, lj) / own[(lj - ty * T) * T + li - tx * T]!;\n }\n function blurredAt(look: { x: number; y: number; z: number }, time: number, nm: number): number {\n const t = geometry.timeDependent ? time : 0, key = keyOf(look, t);\n if (key === undefined) throw new InvalidConfigurationError(\"Defocus query is off the sensor site lattice; the image-space convolution does not apply.\");\n return valueOf(key, t, nm);\n }\n const baseEvaluate = base.evaluateRadiance;\n const evaluateRadiance = (request: Readonly<SceneRadianceEvaluationRequest>): SceneRadianceEvaluationResult => {\n const result = baseEvaluate.call(base, request), o = (request.target as { outgoingDirectionUnitVector: { x: number; y: number; z: number } }).outgoingDirectionUnitVector;\n return { ...result, spectralRadianceWattsPerSquareMeterSteradianNanometer: blurredAt({ x: -o.x, y: -o.y, z: -o.z }, request.timeSecondsFromExposureStart, request.wavelengthNanometers) };\n };\n // The result is the base result with only its radiance replaced, so an engine-built base evaluator keeps its mark. Its radiance is\n // a pure function of the lattice key (and, with rotation, the request time) and the wavelength, so the lean executor may read it by\n // key, as for the diffraction provider.\n if (isInternalSceneRadianceEvaluator(baseEvaluate)) {\n markInternalSceneRadianceEvaluator(evaluateRadiance);\n // With rotation the key also carries the request time, as an index into the distinct times seen (one per temporal midpoint).\n const times: number[] = [], timeIndex = new Map<number, number>(), latticeKeys = shifts.length * LH * LW;\n registerInternalRadianceAccess(evaluateRadiance, {\n tabulated: false,\n keyOfDirection(o, time): number | undefined {\n const t = geometry.timeDependent ? time : 0, key = keyOf({ x: -o.x, y: -o.y, z: -o.z }, t);\n if (key === undefined) return undefined;\n let index = timeIndex.get(t);\n if (index === undefined) { index = times.length; times.push(t); timeIndex.set(t, index); }\n return index * latticeKeys + key;\n },\n radianceOfKey(key, nm): number {\n const index = Math.floor(key / latticeKeys);\n return valueOf(key - index * latticeKeys, times[index]!, nm);\n }\n });\n }\n return {\n sceneId: base.sceneId, providerProfileId: base.providerProfileId, radianceAt: base.radianceAt,\n evaluateRadiance,\n evaluateApertureRadiance(): SceneRadianceEvaluationResult {\n throw new InvalidConfigurationError(\"Defocus by image-space convolution does not take pupil rays.\");\n }\n };\n}\n\n/** Field-variation bounds of the image-space disc for one request (#548), recorded in the `lens.defocus` assumption. */\nexport interface DefocusFieldVariation {\n /** Sensor points the bounds were evaluated at: a grid of this many points per side over the native raster, edges included. */\n gridPointsPerSide: number;\n /**\n * Camera rotation (pitch or yaw tilts the scene plane in the camera frame): the largest change of the disc diameter, in\n * sites, between the axial depth of each scene point in the rotated camera frame and the subject distance, over the grid and\n * the rendered temporal midpoints. 0 for roll only; null without rotation.\n */\n rotationMaximumDiameterChangeSites: number | null;\n /**\n * Distortion: the largest deviation from 1 of the local scale of the distortion map (singular values of d distorted / d ideal)\n * over the grid: the relative disc-size difference to a model that blurs the ideal image and then distorts it. Null without distortion.\n */\n distortionMaximumLocalScaleDeviation: number | null;\n /**\n * A non-rectilinear projection: the largest change of the disc diameter, in sites, between the distance along each scene\n * point's ray and its axial depth (the thin-lens model uses the axial depth). Null for the rectilinear projection.\n */\n projectionMaximumDiameterChangeSites: number | null;\n}\n\n/** Internal: {@link DefocusFieldVariation} on a 9 × 9 grid of sensor points (the extremes of these smooth maps lie on the frame's edges). */\nexport function calculateDefocusFieldVariation(input: { geometry: PreparedDefocusImageSpaceGeometry; lensMapping?: PreparedEnvironmentLensFieldMapping;\n focalLengthMm: number; fNumber: number; focusDistanceM: number; subjectDistanceM: number; pitchMicrometers: number; nativeWidth: number; nativeHeight: number;\n angularVelocityRadPerSec: CameraAngularVelocityRadPerSec; temporalMidpointsSeconds: readonly number[]; diameterSites: number;\n discAt: (subjectDistanceM: number) => number }): DefocusFieldVariation {\n const { geometry, lensMapping, pitchMicrometers: pitch, nativeWidth: W, nativeHeight: H, subjectDistanceM: d, diameterSites, discAt } = input;\n const G = 9, points: { x: number; y: number }[] = [];\n for (let j = 0; j < G; j++) for (let i = 0; i < G; i++) points.push({ x: (i / (G - 1) - 0.5) * W * pitch / 1000, y: (j / (G - 1) - 0.5) * H * pitch / 1000 });\n let rotation: number | null = null;\n if (geometry.timeDependent) {\n rotation = 0;\n const omega = input.angularVelocityRadPerSec;\n for (const t of input.temporalMidpointsSeconds) {\n // The camera's optical axis at t in the reference axes; a scene point's axial depth in the rotated camera is P·axis.\n const axis = applyPhysicalCameraRotation({ x: 0, y: 0, z: 1 }, { pitch: omega.pitch * t, yaw: omega.yaw * t, roll: omega.roll * t }, \"camera-to-reference\");\n for (const p of points) {\n const look = geometry.lookOf(p.x, p.y, t), reach = d / look.z;\n const depth = reach * (look.x * axis.x + look.y * axis.y + look.z * axis.z);\n rotation = Math.max(rotation, Math.abs(discAt(depth) - diameterSites));\n }\n }\n }\n let distortion: number | null = null;\n if (lensMapping && lensMapping.mapping.distortion.kind !== \"none\") {\n distortion = 0;\n for (const p of points) {\n const scales = distortedImagePoint(lensMapping, undistortedImagePoint(lensMapping, { x: p.x, y: -p.y }).ideal);\n distortion = Math.max(distortion, scales.largestScale - 1, 1 - scales.smallestScale);\n }\n }\n let projection: number | null = null;\n if (lensMapping && lensMapping.mapping.projectionModel !== \"rectilinear\") {\n projection = 0;\n for (const p of points) {\n const look = geometry.lookOf(p.x, p.y, 0);\n projection = Math.max(projection, Math.abs(discAt(d / look.z) - diameterSites));\n }\n }\n return { gridPointsPerSide: G, rotationMaximumDiameterChangeSites: rotation, distortionMaximumLocalScaleDeviation: distortion, projectionMaximumDiameterChangeSites: projection };\n}\n"]}
1
+ {"version":3,"file":"defocus-image-space-provider.js","sourceRoot":"","sources":["../../src/facade/defocus-image-space-provider.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * `simulateCapture`'s `lens.defocus` out of focus together with a lens field mapping (`lens.projection`,\n * `lens.distortion`), `lens.vignetting` or camera rotation (#548): the geometric defocus disc applied in image space,\n * on the site lattice of the sensor, instead of on the scene plane.\n *\n * Why the object-space path does not apply. `createDiffractedPlanarProvider` convolves the scene radiance on the plane\n * lattice that the sites see through one linear map (a still, rectilinear, distortion-free camera with the same\n * radiance-to-irradiance factor everywhere). A projection, a distortion or a rotation makes the map from sensor points\n * to plane points non-linear (or time-dependent), and vignetting makes the factor vary over the field, so the disc on\n * the plane is no longer the disc on the sensor.\n *\n * The image-space model. The environment PSF quadrature (`calculateSensorPsfIrradianceQuadrature`, the per-tap path\n * `lens.diffraction` falls back to) defines a sensor-plane PSF K as\n * E(q, λ, t) = Σ_k K(k)·F(s_k)·C·L(D_t(s_k), λ),\n * with s_k = q + k·p the tap source points on the sensor (p the site pitch), D_t the scene ray of a sensor point at\n * time t (inverse distortion, the declared projection, the camera rotation at t), F = T·A the field factor (vignetting\n * throughput T, applied once before the PSF spreads the light, and the distortion area factor A = 1/det J) and C the\n * paraxial radiance-to-irradiance factor π/(4·N_w²), the same everywhere. With K the defocus disc sampled on the site\n * lattice (`createDefocusDiscSiteKernel`), every source point of a site-centre query is another lattice point, so\n * E(q, λ, t) = C·G_t(q, λ), G_t = K ⊛ (F·L∘D_t) sampled on the lattice,\n * the same sum in a different floating-point order. This provider computes G_t once per spectral node and time on the\n * sensor lattice (in row bands, as the diffraction provider does) and answers the query of lattice point q at time t with\n * G_t(q, λ) / F(q); the environment multiplies by F(q)·C again, so each site gets C·G_t(q, λ). For the still,\n * rectilinear, distortion-free camera without vignetting it is the object-space convolution (F = 1 and D linear).\n *\n * The lattices. As in the diffraction provider, a pixel aperture or anti-aliasing spots add query offsets; each distinct\n * fractional offset gets its own shifted lattice of sensor points, and every tap of a query on one lattice is on the same\n * lattice. A query is located on its lattice by mapping its scene ray back to the sensor (camera rotation inverted at the\n * request's time, the forward projection, the forward distortion), within 1e-4 site; a query that lands on no lattice point\n * is refused rather than approximated.\n *\n * Time. With camera rotation each environment temporal midpoint is a still camera, so the disc is applied to that\n * instant's image in that instant's frame: one G_t per distinct request time, cached per band. Without rotation the image\n * does not depend on time and one G is kept. The facade refuses rotation with a rolling shutter (each row's instants differ).\n *\n * What is approximate is the disc itself (`lens.defocus` labels it; the facade records the field-variation bounds of\n * each combination), not this evaluation of it.\n */\n\n// #564: a defocus kernel above 64 sites (`largeKernel`) takes the run lattice of large-defocus-lattice.ts instead of the bands:\n// the samples F·L at the same lattice points, convolved by runs in fixed tiles, then divided by each queried point's own F.\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { hypot3 } from \"../core/portable-math.js\";\nimport { isInternalSceneRadianceEvaluator, markInternalSceneRadianceEvaluator, registerInternalRadianceAccess } from \"../core/internal-radiance-evaluator.js\";\nimport type { SceneRadianceEvaluationRequest, SceneRadianceEvaluationResult } from \"../schema/scene-radiance.js\";\nimport { insideRadialImageCircle, lensProjectionDirectionValue, lensProjectionImagePointValue, type LensProjectionModel } from \"../camera/lens-projection.js\";\nimport { applyPhysicalCameraRotation, resolveProjectionDistanceMm, type CameraAngularVelocityRadPerSec } from \"../motion/camera-rotation.js\";\nimport { prepareIlluminationVignettingThroughput, type IlluminationVignettingProfile } from \"../optics/illumination-vignetting.js\";\nimport { distortedImagePoint, undistortedImagePoint, type PreparedEnvironmentLensFieldMapping } from \"../optics/sensor-environment-query.js\";\nimport { checkedSiteKernel, createZonedGather, gatherInterior, kernelTaps, type SiteKernelFieldZones } from \"./diffraction-provider.js\";\nimport type { PlanarSceneRadianceProvider } from \"./scene-radiance.js\";\nimport { LARGE_DEFOCUS_CACHE_BYTES, createLargeDefocusNodeLattice, type LargeDefocusKernel, type LargeDefocusNodeLattice } from \"./large-defocus-lattice.js\";\n\n/** Rows of native sites per band; bands kept per time. Banding changes memory only, never values. */\nconst BAND_ROWS = 32;\nconst CACHED_BANDS = 2;\nconst LATTICE_TOLERANCE_SITES = 1e-4;\n\n/** The camera geometry the environment uses for each site query (the same options as the site inputs). */\nexport interface DefocusImageSpaceGeometry {\n focalLengthMm: number;\n focusDistanceM: number;\n angularVelocityRadPerSec: CameraAngularVelocityRadPerSec;\n /** The site inputs' `lensFieldMapping`, prepared; omitted for the ideal rectilinear, distortion-free mapping. */\n lensMapping?: PreparedEnvironmentLensFieldMapping;\n /** The site inputs' radial-illumination-vignetting profile; omitted for unity field throughput. */\n vignetting?: IlluminationVignettingProfile;\n}\n\n/** Internal: the scene ray and field factor of sensor points, and the sensor point of a scene ray, for one geometry. */\nexport interface PreparedDefocusImageSpaceGeometry {\n /**\n * The unit look direction (toward the scene, reference camera axes at exposure start) of native sensor point (x, y) mm\n * (+X right, +Y down) at time t, and its field factor F = T·A (vignetting throughput × distortion area factor).\n */\n lookOf(xMm: number, yMm: number, timeSeconds: number): { x: number; y: number; z: number; factor: number };\n /** The native sensor point (mm, +Y down) whose scene ray at time t is the look direction; undefined outside the mapping. */\n sensorPointOf(look: { x: number; y: number; z: number }, timeSeconds: number): { x: number; y: number } | undefined;\n /** True with camera rotation: the ray of a sensor point depends on time. */\n timeDependent: boolean;\n}\n\n/** Internal: prepares {@link PreparedDefocusImageSpaceGeometry} with the environment's own conventions and arithmetic. */\nexport function prepareDefocusImageSpaceGeometry(geometry: DefocusImageSpaceGeometry): PreparedDefocusImageSpaceGeometry {\n const { focalLengthMm, focusDistanceM, angularVelocityRadPerSec: omega, lensMapping, vignetting } = geometry;\n // The projection scale: the thin-lens image distance at the finite focus, for every projection model (the environment's).\n const pd = resolveProjectionDistanceMm(focalLengthMm, focusDistanceM).projectionDistanceMm;\n const model: LensProjectionModel = lensMapping?.mapping.projectionModel ?? \"rectilinear\";\n // #569: with \"backward-ray\" (catalogue fisheyes), a point outside the image circle looks straight back, as the environment's mapped query does.\n const backward = lensMapping?.mapping.outsideImageCircle === \"backward-ray\";\n const timeDependent = omega.pitch !== 0 || omega.yaw !== 0 || omega.roll !== 0;\n // calculateIlluminationVignetting's throughput with the profile validated once (#563: the same numbers, without a result envelope per point).\n const throughputAt = vignetting ? prepareIlluminationVignettingThroughput(vignetting) : undefined;\n const displacement = (t: number): { pitch: number; yaw: number; roll: number } =>\n timeDependent ? { pitch: omega.pitch * t, yaw: omega.yaw * t, roll: omega.roll * t } : { pitch: 0, yaw: 0, roll: 0 };\n // The reference-to-camera rotation at the last time asked, as a matrix (its columns: the rotated basis vectors), so a lattice\n // lookup costs no trigonometry; the rotation is linear, so this equals rotating the vector, up to rounding.\n let matrixTime = NaN, m: number[] = [];\n const toCamera = (v: { x: number; y: number; z: number }, t: number): { x: number; y: number; z: number } => {\n if (t !== matrixTime) {\n const d = displacement(t), ex = applyPhysicalCameraRotation({ x: 1, y: 0, z: 0 }, d, \"reference-to-camera\"),\n ey = applyPhysicalCameraRotation({ x: 0, y: 1, z: 0 }, d, \"reference-to-camera\"), ez = applyPhysicalCameraRotation({ x: 0, y: 0, z: 1 }, d, \"reference-to-camera\");\n m = [ex.x, ey.x, ez.x, ex.y, ey.y, ez.y, ex.z, ey.z, ez.z];\n matrixTime = t;\n }\n return { x: m[0]! * v.x + m[1]! * v.y + m[2]! * v.z, y: m[3]! * v.x + m[4]! * v.y + m[5]! * v.z, z: m[6]! * v.x + m[7]! * v.y + m[8]! * v.z };\n };\n return {\n timeDependent,\n lookOf(xMm, yMm, t): { x: number; y: number; z: number; factor: number } {\n const image = { x: xMm, y: -yMm };\n const { ideal, distortionAreaFactor } = lensMapping ? undistortedImagePoint(lensMapping, image) : { ideal: image, distortionAreaFactor: 1 };\n let lx: number, ly: number, lz: number;\n if (model === \"rectilinear\") {\n // calculateInverseCameraRotationImageMapping: the captured ray (x/pd, y/pd, 1) in reference axes, projected at pd.\n const reference = applyPhysicalCameraRotation({ x: ideal.x / pd, y: ideal.y / pd, z: 1 }, displacement(t), \"camera-to-reference\");\n if (!(reference.z > 0)) throw new InvalidConfigurationError(\"lens.defocus: a lattice point's ray points to or behind the reference camera plane.\");\n lx = pd * (reference.x / reference.z); ly = pd * (reference.y / reference.z); lz = pd;\n } else {\n const reference = applyPhysicalCameraRotation(backward && !insideRadialImageCircle(model, pd, Math.hypot(ideal.x, ideal.y)) ? { x: 0, y: 0, z: -1 } :\n lensProjectionDirectionValue(model, pd, ideal.x, ideal.y), displacement(t), \"camera-to-reference\");\n lx = reference.x; ly = reference.y; lz = reference.z;\n }\n const length = hypot3(lx, ly, lz);\n const throughput = throughputAt ? throughputAt(image) : 1;\n return { x: lx / length, y: ly / length, z: lz / length, factor: throughput * distortionAreaFactor };\n },\n sensorPointOf(look, t): { x: number; y: number } | undefined {\n try {\n const c = timeDependent ? toCamera(look, t) : look;\n let ideal: { x: number; y: number };\n if (model === \"rectilinear\") {\n if (!(c.z > 0)) return undefined;\n ideal = { x: pd * (c.x / c.z), y: pd * (c.y / c.z) };\n } else ideal = lensProjectionImagePointValue(model, pd, c.x, c.y, c.z).imagePointMm;\n const image = lensMapping ? distortedImagePoint(lensMapping, ideal).pointMm : ideal;\n return Number.isFinite(image.x) && Number.isFinite(image.y) ? { x: image.x, y: -image.y } : undefined;\n } catch {\n return undefined;\n }\n }\n };\n}\n\nexport interface DefocusImageSpaceProviderInput {\n base: PlanarSceneRadianceProvider;\n geometry: PreparedDefocusImageSpaceGeometry;\n /** Each spectral node's kernel on the site lattice, (2·kernelRadius + 1)² taps, row-major (the disc, or diffraction ⊛ disc). */\n siteKernels: (wavelengthNm: number) => Float64Array;\n wavelengthsNm: readonly number[];\n kernelRadius: number;\n nativeWidth: number;\n nativeHeight: number;\n sitePitchMicrometers: number;\n /** Planar geometry of the base provider (plane distance and frame-unit scale), to find the plane point of a ray as it does. */\n distanceM: number;\n metresPerFrameUnit: number;\n /** Offsets of the query points from the site centres, in sites (+x right, +y down). Default: one zero offset. */\n queryOffsetsSites?: readonly { x: number; y: number }[];\n /** Region renders: the native sites that will be queried. Values are bit-identical to the whole render's. Default: the whole raster. */\n window?: { x: number; y: number; width: number; height: number };\n /** #551: the scene itself depends on time (a moving subject): each request time keeps its own image even without rotation. */\n timeDependentScene?: boolean;\n /** Most distinct request times kept per band (the temporal sample count). Default 1. */\n timesPerBand?: number;\n /** Called with the duration in ms of each band convolution (diagnostics only). */\n onConvolution?: (milliseconds: number) => void;\n /**\n * #564: a defocus kernel above the direct radius, convolved by runs in fixed tiles (`large-defocus-lattice.ts`), with each\n * node's diffraction kernel after it; used instead of `siteKernels` (`kernelRadius` is then unused).\n */\n largeKernel?: LargeDefocusKernel;\n /** #553: a field-varying kernel by zones (the cat's eye of lens.defocus), gathered instead of `siteKernels`, the same at every node. */\n fieldZones?: SiteKernelFieldZones;\n /**\n * #588, catalogue fisheyes (with the base provider's own `zeroBeyondHorizon`): a lattice point whose ray is at or beyond 90°\n * sees no scene (zero radiance), and a query in such a direction gets the base provider's zero, instead of failing.\n */\n zeroBeyondHorizon?: boolean;\n}\n\n/** Internal (not exported from the package): the base provider with the defocus disc applied in image space (#548). */\nexport function createDefocusImageSpaceProvider(input: DefocusImageSpaceProviderInput): PlanarSceneRadianceProvider {\n const { base, geometry, wavelengthsNm, nativeWidth: W, nativeHeight: H, kernelRadius: R } = input;\n const mmPerSite = input.sitePitchMicrometers / 1000;\n const index = new Map(wavelengthsNm.map((nm, i) => [nm, i]));\n const offsets = input.queryOffsetsSites ?? [{ x: 0, y: 0 }];\n const fraction = (value: number): number => { const f = value - Math.floor(value); return f > 1 - 1e-6 ? 0 : f < 1e-6 ? 0 : f; };\n const shifts: { x: number; y: number }[] = [];\n for (const o of offsets) {\n const f = { x: fraction(o.x), y: fraction(o.y) };\n if (!shifts.some((s) => Math.abs(s.x - f.x) <= 1e-6 && Math.abs(s.y - f.y) <= 1e-6)) shifts.push(f);\n }\n const M = Math.max(0, ...offsets.map((o) => Math.ceil(Math.max(Math.abs(o.x), Math.abs(o.y)) - 1e-6)));\n const LW = W + 2 * M, LH = H + 2 * M;\n const win = input.window ?? { x: 0, y: 0, width: W, height: H };\n const lx0 = Math.max(0, win.x), lx1 = Math.min(LW, win.x + win.width + 2 * M);\n const ly0 = Math.max(0, win.y), ly1 = Math.min(LH, win.y + win.height + 2 * M);\n if (!(lx0 < lx1 && ly0 < ly1)) throw new InvalidConfigurationError(\"Defocus window must overlap the native raster.\");\n const NW = lx1 - lx0, gridWidth = NW + 2 * R;\n const large = input.largeKernel;\n const kernels = large ? [] : wavelengthsNm.map((nm) => checkedSiteKernel(input.siteKernels(nm), R));\n const taps = kernels.map((kernel) => kernelTaps(kernel, R, gridWidth));\n const zonedGather = input.fieldZones ? createZonedGather(input.fieldZones, R, gridWidth, W, H, M) : undefined;\n const sharedKernel = !large && (zonedGather !== undefined || kernels.every((kernel) => kernel === kernels[0]));\n const scale = input.metresPerFrameUnit, distance = input.distanceM;\n const materialAt = base.chartMaterialAt?.bind(base), materialRadiance = base.materialRadiance?.bind(base), zeroBeyond = input.zeroBeyondHorizon === true;\n const timeDependent = geometry.timeDependent || input.timeDependentScene === true;\n const now = (): number => globalThis.performance?.now() ?? Date.now();\n // Lattice point (li, lj) of shift s, as a native sensor point in mm (+Y down): site centre plus the shift.\n const xMmOf = (li: number, s: { x: number }): number => (li - M + 0.5 + s.x - W / 2) * mmPerSite;\n const yMmOf = (lj: number, s: { y: number }): number => (lj - M + 0.5 + s.y - H / 2) * mmPerSite;\n // Lattice point k's field factor and plane point (or material) from its sensor point; #588: beyond the horizon it keeps factor 0\n // (a zero sample at the plane's origin), and such a point is never queried (evaluateRadiance).\n function mapInto(k: number, xMm: number, yMm: number, time: number, factor: Float64Array, u: Float64Array, v: Float64Array, material: Int32Array | undefined): void {\n const look = geometry.lookOf(xMm, yMm, time);\n if (!(look.z > 0)) { if (zeroBeyond) return; throw new InvalidConfigurationError(\"lens.defocus: a lattice point's ray does not point toward the scene plane.\"); }\n // The base provider's own plane-point arithmetic for the outgoing direction −look.\n const t = distance / look.z;\n factor[k] = look.factor; u[k] = look.x * t / scale; v[k] = look.y * t / scale;\n if (material) material[k] = materialAt!(u[k]!, v[k]!);\n }\n // The samples F·L at one spectral node (a point with factor 0 gives 0).\n function samplesOf(nm: number, time: number, factor: Float64Array, u: Float64Array, v: Float64Array, material: Int32Array | undefined): Float64Array {\n const size = factor.length, samples = new Float64Array(size);\n if (material) {\n const radiance = new Map<number, number>();\n for (let k = 0; k < size; k++) {\n const m = material[k]!;\n let value = radiance.get(m);\n if (value === undefined) { value = materialRadiance!(m, nm); radiance.set(m, value); }\n samples[k] = factor[k]! * value;\n }\n } else for (let k = 0; k < size; k++) samples[k] = factor[k]! * base.radianceAt(u[k]!, v[k]!, nm, time);\n return samples;\n }\n // Bands per time (LRU over (time, band)): values[shift][node] holds G_t / F at the band's own lattice points.\n const cache = new Map<string, Float64Array[][]>();\n const capacity = CACHED_BANDS * Math.max(1, input.timesPerBand ?? 1);\n // The last band read, so consecutive queries of one band skip the cache key (most queries).\n let lastBand = -1, lastTime = NaN, lastValues: Float64Array[][] | undefined;\n function band(b: number, time: number): Float64Array[][] {\n if (b === lastBand && time === lastTime) return lastValues!;\n const values = bandOf(b, time);\n lastBand = b; lastTime = time; lastValues = values;\n return values;\n }\n\n function bandOf(b: number, time: number): Float64Array[][] {\n const key = time + \":\" + b, cached = cache.get(key);\n if (cached) { cache.delete(key); cache.set(key, cached); return cached; }\n const started = input.onConvolution ? now() : 0;\n const y0 = ly0 + b * BAND_ROWS, rows = Math.min(BAND_ROWS, ly1 - y0), gridHeight = rows + 2 * R, size = gridWidth * gridHeight;\n const values = shifts.map((shift) => {\n // Each grid point's field factor and plane point (or material), shared by the spectral nodes.\n const factor = new Float64Array(size), u = new Float64Array(size), v = new Float64Array(size);\n const material = materialAt && materialRadiance ? new Int32Array(size) : undefined;\n for (let gy = 0; gy < gridHeight; gy++) {\n const yMm = yMmOf(y0 + gy - R, shift);\n for (let gx = 0; gx < gridWidth; gx++) mapInto(gy * gridWidth + gx, xMmOf(lx0 + gx - R, shift), yMm, time, factor, u, v, material);\n }\n // The band's own lattice points' factors, to answer each query with G / F.\n const own = new Float64Array(rows * NW);\n for (let y = 0; y < rows; y++) for (let x = 0; x < NW; x++) own[y * NW + x] = factor[(y + R) * gridWidth + x + R]!;\n // One kernel for every node (the disc without diffraction) and fewer materials than nodes: the convolution is linear, so\n // G_λ = Σ_m L_m(λ)·(K ⊛ F·[material = m]); one convolution per material instead of one per node, the same sum regrouped.\n if (material && sharedKernel) {\n const present = [...new Set(material)];\n if (present.length < wavelengthsNm.length) {\n const perMaterial = present.map((m) => {\n const samples = new Float64Array(size);\n for (let k = 0; k < size; k++) if (material[k] === m) samples[k] = factor[k]!;\n return zonedGather ? zonedGather(samples, lx0, y0, NW, rows) : gatherInterior(samples, taps[0]!, gridWidth, NW, rows, R);\n });\n return wavelengthsNm.map((nm) => {\n const radiance = present.map((m) => materialRadiance!(m, nm)), out = new Float64Array(rows * NW);\n for (const value of radiance) if (!(value >= 0 && value <= 2 ** 100)) throw new InvalidConfigurationError(\"Irradiance samples must be finite, non-negative and within the declared magnitude.\");\n for (let k = 0; k < out.length; k++) {\n let sum = 0;\n for (let i = 0; i < present.length; i++) sum += radiance[i]! * perMaterial[i]![k]!;\n out[k] = sum / own[k]!;\n }\n return out;\n });\n }\n }\n return wavelengthsNm.map((nm, w) => {\n const samples = samplesOf(nm, time, factor, u, v, material);\n const gathered = zonedGather ? zonedGather(samples, lx0, y0, NW, rows) : gatherInterior(samples, taps[w]!, gridWidth, NW, rows, R);\n for (let k = 0; k < gathered.length; k++) gathered[k] = gathered[k]! / own[k]!;\n return gathered;\n });\n });\n cache.set(key, values);\n if (cache.size > capacity) cache.delete(cache.keys().next().value!);\n if (input.onConvolution) input.onConvolution(now() - started);\n return values;\n }\n /** The lattice key ((shift·LH + lj)·LW + li) of a look direction at time t, or undefined off the lattices or outside the window. */\n function keyOf(look: { x: number; y: number; z: number }, t: number): number | undefined {\n const point = geometry.sensorPointOf(look, t);\n if (point === undefined) return undefined;\n const fi = point.x / mmPerSite + W / 2 - 0.5, fj = point.y / mmPerSite + H / 2 - 0.5;\n for (let s = 0; s < shifts.length; s++) {\n const shift = shifts[s]!, i = Math.round(fi - shift.x), j = Math.round(fj - shift.y);\n if (Math.abs(fi - shift.x - i) > LATTICE_TOLERANCE_SITES || Math.abs(fj - shift.y - j) > LATTICE_TOLERANCE_SITES) continue;\n const li = i + M, lj = j + M;\n if (li < lx0 || lj < ly0 || li >= lx1 || lj >= ly1) return undefined;\n return (s * LH + lj) * LW + li;\n }\n return undefined;\n }\n function valueOf(key: number | undefined, t: number, nm: number): number {\n const w = index.get(nm);\n if (w === undefined || key === undefined) throw new InvalidConfigurationError(\"Defocus query is off the sensor site lattice; the image-space convolution does not apply.\");\n const li = key % LW, rest = (key - li) / LW, lj = rest % LH, s = (rest - lj) / LH;\n if (large) return largeValue(s, t, w, li, lj);\n return band(Math.floor((lj - ly0) / BAND_ROWS), t)[s]![w]![((lj - ly0) % BAND_ROWS) * NW + li - lx0]!;\n }\n // #564: one run lattice per (time, shift) of the samples F·L at the lattice points, and the own field factors F by tile, so a\n // query is answered with (K ⊛ D ⊛ F·L) / F as on the band path.\n const largeLattices = new Map<string, { lattice: LargeDefocusNodeLattice; own: Map<number, Float64Array> }>();\n const largeLatticeCount = shifts.length * Math.max(1, input.timesPerBand ?? 1);\n // Lattice points at most `reach` beyond the lattice feed queried values: the defocus kernel's radius plus the diffraction kernel's.\n const reach = large ? large.runs.radius + (large.diffraction ? large.diffraction.radius : 0) : 0;\n function largeValue(s: number, time: number, w: number, li: number, lj: number): number {\n const key = time + \":\" + s;\n let entry = largeLattices.get(key);\n if (!entry) {\n const shift = shifts[s]!;\n const lattice = createLargeDefocusNodeLattice({ kernel: large!, wavelengthsNm, capacityBytes: LARGE_DEFOCUS_CACHE_BYTES / largeLatticeCount, ...(input.onConvolution ? { onTile: input.onConvolution } : {}),\n source: (x0, y0, width, height) => {\n const size = width * height, factor = new Float64Array(size), u = new Float64Array(size), v = new Float64Array(size);\n const material = materialAt && materialRadiance ? new Int32Array(size) : undefined;\n for (let y = 0; y < height; y++) {\n const yMm = yMmOf(y0 + y, shift);\n for (let x = 0; x < width; x++) {\n // A fixed tile's source reaches past the lattice: points beyond its reach feed no queried value, so they keep factor 0\n // (sample 0) and are never mapped (the lens profiles are checked only up to the reach).\n if (x0 + x < -reach || x0 + x >= LW + reach || y0 + y < -reach || y0 + y >= LH + reach) continue;\n mapInto(y * width + x, xMmOf(x0 + x, shift), yMm, time, factor, u, v, material);\n }\n }\n return (node: number): Float64Array => samplesOf(wavelengthsNm[node]!, time, factor, u, v, material);\n } });\n entry = { lattice, own: new Map() };\n largeLattices.set(key, entry);\n if (largeLattices.size > largeLatticeCount) largeLattices.delete(largeLattices.keys().next().value!);\n }\n // The own factor of the lattice point, by 64-point tiles (kept for the request: 8 bytes per lattice point read).\n const T = 64, tx = Math.floor(li / T), ty = Math.floor(lj / T), tileKey = ty * 1048576 + tx;\n let own = entry.own.get(tileKey);\n if (!own) {\n own = new Float64Array(T * T);\n const shift = shifts[s]!;\n // Only the lattice's own points are queried; the rest of the tile is never read (and may lie beyond the lens profiles).\n for (let y = 0; y < T && ty * T + y < LH; y++) { const yMm = yMmOf(ty * T + y, shift); for (let x = 0; x < T && tx * T + x < LW; x++) own[y * T + x] = geometry.lookOf(xMmOf(tx * T + x, shift), yMm, time).factor; }\n entry.own.set(tileKey, own);\n }\n return entry.lattice.valueAt(w, li, lj) / own[(lj - ty * T) * T + li - tx * T]!;\n }\n function blurredAt(look: { x: number; y: number; z: number }, time: number, nm: number): number {\n const t = timeDependent ? time : 0;\n return valueOf(keyOf(look, t), t, nm);\n }\n const baseEvaluate = base.evaluateRadiance, internal = isInternalSceneRadianceEvaluator(baseEvaluate);\n const evaluateRadiance = (request: Readonly<SceneRadianceEvaluationRequest>): SceneRadianceEvaluationResult => {\n const result = baseEvaluate.call(base, request), o = (request.target as { outgoingDirectionUnitVector: { x: number; y: number; z: number } }).outgoingDirectionUnitVector;\n // #588: at or beyond the horizon the base provider's own zero.\n if (zeroBeyond && !(o.z < 0)) return result;\n const radiance = blurredAt({ x: -o.x, y: -o.y, z: -o.z }, request.timeSecondsFromExposureStart, request.wavelengthNanometers);\n // #588: an engine-built base returns a new result object per call, so its radiance is replaced in place (no copy per query).\n if (internal) { (result as { spectralRadianceWattsPerSquareMeterSteradianNanometer: number }).spectralRadianceWattsPerSquareMeterSteradianNanometer = radiance; return result; }\n return { ...result, spectralRadianceWattsPerSquareMeterSteradianNanometer: radiance };\n };\n // The result is the base result with only its radiance replaced, so an engine-built base evaluator keeps its mark. Its radiance is\n // a pure function of the lattice key (and, with rotation, the request time) and the wavelength, so the lean executor may read it by\n // key, as for the diffraction provider.\n if (internal) {\n markInternalSceneRadianceEvaluator(evaluateRadiance);\n // With rotation the key also carries the request time, as an index into the distinct times seen (one per temporal midpoint).\n const times: number[] = [], timeIndex = new Map<number, number>(), latticeKeys = shifts.length * LH * LW;\n registerInternalRadianceAccess(evaluateRadiance, {\n tabulated: false,\n keyOfDirection(o, time): number | undefined {\n const t = timeDependent ? time : 0, key = keyOf({ x: -o.x, y: -o.y, z: -o.z }, t);\n if (key === undefined) return undefined;\n let index = timeIndex.get(t);\n if (index === undefined) { index = times.length; times.push(t); timeIndex.set(t, index); }\n return index * latticeKeys + key;\n },\n radianceOfKey(key, nm): number {\n const index = Math.floor(key / latticeKeys);\n return valueOf(key - index * latticeKeys, times[index]!, nm);\n }\n });\n }\n return {\n sceneId: base.sceneId, providerProfileId: base.providerProfileId, radianceAt: base.radianceAt,\n evaluateRadiance,\n evaluateApertureRadiance(): SceneRadianceEvaluationResult {\n throw new InvalidConfigurationError(\"Defocus by image-space convolution does not take pupil rays.\");\n }\n };\n}\n\n/** Field-variation bounds of the image-space disc for one request (#548), recorded in the `lens.defocus` assumption. */\nexport interface DefocusFieldVariation {\n /** Sensor points the bounds were evaluated at: a grid of this many points per side over the native raster, edges included. */\n gridPointsPerSide: number;\n /**\n * Camera rotation (pitch or yaw tilts the scene plane in the camera frame): the largest change of the disc diameter, in\n * sites, between the axial depth of each scene point in the rotated camera frame and the subject distance, over the grid and\n * the rendered temporal midpoints. 0 for roll only; null without rotation.\n */\n rotationMaximumDiameterChangeSites: number | null;\n /**\n * Distortion: the largest deviation from 1 of the local scale of the distortion map (singular values of d distorted / d ideal)\n * over the grid: the relative disc-size difference to a model that blurs the ideal image and then distorts it. Null without distortion.\n */\n distortionMaximumLocalScaleDeviation: number | null;\n /**\n * A non-rectilinear projection: the largest change of the disc diameter, in sites, between the distance along each scene\n * point's ray and its axial depth (the thin-lens model uses the axial depth). Null for the rectilinear projection.\n */\n projectionMaximumDiameterChangeSites: number | null;\n}\n\n/** Internal: {@link DefocusFieldVariation} on a 9 × 9 grid of sensor points (the extremes of these smooth maps lie on the frame's edges). */\nexport function calculateDefocusFieldVariation(input: { geometry: PreparedDefocusImageSpaceGeometry; lensMapping?: PreparedEnvironmentLensFieldMapping;\n focalLengthMm: number; fNumber: number; focusDistanceM: number; subjectDistanceM: number; pitchMicrometers: number; nativeWidth: number; nativeHeight: number;\n angularVelocityRadPerSec: CameraAngularVelocityRadPerSec; temporalMidpointsSeconds: readonly number[]; diameterSites: number;\n discAt: (subjectDistanceM: number) => number }): DefocusFieldVariation {\n const { geometry, lensMapping, pitchMicrometers: pitch, nativeWidth: W, nativeHeight: H, subjectDistanceM: d, diameterSites, discAt } = input;\n const G = 9, points: { x: number; y: number }[] = [];\n for (let j = 0; j < G; j++) for (let i = 0; i < G; i++) points.push({ x: (i / (G - 1) - 0.5) * W * pitch / 1000, y: (j / (G - 1) - 0.5) * H * pitch / 1000 });\n let rotation: number | null = null;\n if (geometry.timeDependent) {\n rotation = 0;\n const omega = input.angularVelocityRadPerSec;\n for (const t of input.temporalMidpointsSeconds) {\n // The camera's optical axis at t in the reference axes; a scene point's axial depth in the rotated camera is P·axis.\n const axis = applyPhysicalCameraRotation({ x: 0, y: 0, z: 1 }, { pitch: omega.pitch * t, yaw: omega.yaw * t, roll: omega.roll * t }, \"camera-to-reference\");\n for (const p of points) {\n const look = geometry.lookOf(p.x, p.y, t), reach = d / look.z;\n const depth = reach * (look.x * axis.x + look.y * axis.y + look.z * axis.z);\n rotation = Math.max(rotation, Math.abs(discAt(depth) - diameterSites));\n }\n }\n }\n let distortion: number | null = null;\n if (lensMapping && lensMapping.mapping.distortion.kind !== \"none\") {\n distortion = 0;\n for (const p of points) {\n const scales = distortedImagePoint(lensMapping, undistortedImagePoint(lensMapping, { x: p.x, y: -p.y }).ideal);\n distortion = Math.max(distortion, scales.largestScale - 1, 1 - scales.smallestScale);\n }\n }\n let projection: number | null = null;\n if (lensMapping && lensMapping.mapping.projectionModel !== \"rectilinear\") {\n projection = 0;\n for (const p of points) {\n const look = geometry.lookOf(p.x, p.y, 0);\n projection = Math.max(projection, Math.abs(discAt(d / look.z) - diameterSites));\n }\n }\n return { gridPointsPerSide: G, rotationMaximumDiameterChangeSites: rotation, distortionMaximumLocalScaleDeviation: distortion, projectionMaximumDiameterChangeSites: projection };\n}\n"]}
@@ -80,6 +80,8 @@ export async function openDisplayViewGpuSession(options, request, signal) {
80
80
  if (request.lens)
81
81
  return fallBack(options, "unsupported-on-backend", "the GPU display-view renderers do not render lens.projection, lens.distortion, lens.vignetting or " +
82
82
  "camera rotation (#563); the CPU reference renders them. No device was requested.");
83
+ if (request.mixedIllumination)
84
+ return fallBack(options, "unsupported-on-backend", "the GPU renderers light chart materials with one illuminant; the CPU reference renders mixed illumination (#550). No device was requested.");
83
85
  let runtime, owned = false;
84
86
  if (isAccelerator(options.gpuDevice)) {
85
87
  const shared = acceleratorRuntime(options.gpuDevice);
@@ -1 +1 @@
1
- {"version":3,"file":"display-view-gpu-session.js","sourceRoot":"","sources":["../../src/facade/display-view-gpu-session.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * #481: the device handling behind `prepareDisplayView(request, { gpu: \"auto\" | \"require\", gpuDevice })`. Loaded on demand by\n * `simulate-display-view.ts`, so the GPU code stays out of bundles that never ask for it. One session per prepared view:\n *\n * - the realm's switch (`setWebGpuEnabled(false)`) vetoes before anything else: `\"auto\"` falls back with `webgpu-disabled`,\n * `\"require\"` throws it;\n * - with no renderer registered (the engine registers its renderer, the Speed and Quality kernels of #478 and #479, when this module\n * loads; a caller may replace it or set null) no device is requested: `unsupported-on-backend`;\n * - the device is the handle's (`gpuDevice`: an `ImageKernelAccelerator`'s device, shared and left to its owner, or a WebGPU\n * entry point to acquire from), or acquired from `navigator.gpu` and owned by the session; the accelerator's acquisition\n * reasons apply, and the request's `signal` aborts the acquisition;\n * - the renderer must support the request, else `unsupported-on-backend`; a render the renderer refuses only when rendering\n * (`unsupported-on-backend` thrown by `render`: a coarse view, a device that fails the composite chart probe, #491) runs the\n * CPU reference for that render with the same label, and so does a render whose tables or bands exceed the device's limits\n * (`insufficient-limits` thrown by `render`: #492, a large defocus kernel's table on a scene of many materials);\n * - before the first GPU render on the device a short conformance self-check runs once (single-flight): the built-in cases run\n * the existing `webgpu-f32` convolution kernel against the float64 reference within its a-priori bound, then the renderer's own\n * cases; a failure keeps the whole view on the CPU, labelled `conformance-failed`, with the adapter recorded;\n * - GPU renders of one session run one at a time on the device (the accelerator's single flight; later renders wait);\n * - a lost device falls back to the CPU for that render and every later one, labelled `device-lost`; `dispose()` releases an\n * owned device, and later renders run on the CPU labelled `disposed`.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { getWebGpuEnabled } from \"../gpu/webgpu-switch.js\";\nimport { acquireWebGpuRuntime, type WebGpuRuntime } from \"../gpu/webgpu-runtime.js\";\nimport { ImageKernelExecutionError, WEBGPU_F32_LIMITATIONS, type ChartCompositeProbeRecord, type ImageKernelAdapterDescription } from \"../gpu/image-kernel-execution.js\";\nimport { acceleratorRuntime, convolveIrradianceOnRuntime } from \"../gpu/image-kernel-accelerator.js\";\nimport { calculateIrradianceConvolutionPlan, convolveIrradianceRows, type IrradianceConvolutionInput } from \"../optics/irradiance-convolution.js\";\nimport type { DisplayViewRenderResult, DisplayViewSetup } from \"./display-view.js\";\nimport { displayViewGpuRendererFactory as engineDisplayViewGpuRendererFactory } from \"../gpu/display-view-quality-gpu.js\";\nimport { cpuDisplayViewExecution, displayViewGpuRendererFactory, setDisplayViewGpuRendererFactory, type DisplayViewExecution, type DisplayViewGpuConformance, type DisplayViewGpuConformanceCase,\n type DisplayViewGpuFallbackReason, type DisplayViewGpuRenderer, type DisplayViewGpuRequest, type ParsedPrepareDisplayViewOptions } from \"./display-view-gpu.js\";\n\n// #478, #479: the engine's own renderer, the display view's Speed and Quality kernels behind one renderer\n// (`src/gpu/display-view-quality-gpu.ts`), is registered when this module loads (that is, when a prepared view first asks for the\n// GPU) unless a caller registered a renderer before; a test that needs \"no renderer\" sets the factory to null.\nif (displayViewGpuRendererFactory() === null) setDisplayViewGpuRendererFactory(engineDisplayViewGpuRendererFactory);\n\n/** Internal: the GPU side of one prepared view. */\nexport interface DisplayViewGpuSession {\n /** Renders `setup` on the GPU when the session can, else through `cpu`; the label says which ran. */\n render(setup: DisplayViewSetup, signal: AbortSignal | undefined, cpu: () => Promise<DisplayViewRenderResult>): Promise<{ rendered: DisplayViewRenderResult; execution: DisplayViewExecution }>;\n dispose(): void;\n}\n\n/** A session that renders every view on the CPU with one fixed reason. */\nfunction cpuSession(options: ParsedPrepareDisplayViewOptions, reason: DisplayViewGpuFallbackReason, detail: string, adapter: ImageKernelAdapterDescription | null,\n conformance: DisplayViewGpuConformance | null): DisplayViewGpuSession {\n const execution = cpuDisplayViewExecution(options.gpu, reason, adapter, conformance, detail);\n return { async render(_setup, _signal, cpu): Promise<{ rendered: DisplayViewRenderResult; execution: DisplayViewExecution }> { return { rendered: await cpu(), execution }; },\n dispose(): void { /* nothing acquired */ } };\n}\n\n/** `\"require\"` throws the reason; `\"auto\"` gets a CPU session labelled with it. */\nfunction fallBack(options: ParsedPrepareDisplayViewOptions, reason: DisplayViewGpuFallbackReason, detail: string, adapter: ImageKernelAdapterDescription | null = null,\n conformance: DisplayViewGpuConformance | null = null): DisplayViewGpuSession {\n if (options.gpu === \"require\") throw requireError(reason, detail);\n return cpuSession(options, reason, detail, adapter, conformance);\n}\n/**\n * The error `\"require\"` throws instead of falling back. Every display-view fallback reason is also a failure reason of the accelerator's\n * error. A refusal by the composite chart probe carries its record as `probe` (the structured detail of the message).\n */\nfunction requireError(reason: DisplayViewGpuFallbackReason, detail: string, probe: ChartCompositeProbeRecord | null = null): ImageKernelExecutionError {\n const error = new ImageKernelExecutionError(reason, \"prepareDisplayView with gpu \\\"require\\\": \" + detail);\n if (probe) Object.defineProperty(error, \"probe\", { value: probe, enumerable: true });\n return error;\n}\n/** The composite chart probe's record on a refusal (`ChartCompositeProbeError.probe`), or null. */\nfunction probeOf(error: unknown): ChartCompositeProbeRecord | null {\n const probe = (error as { probe?: unknown }).probe;\n return typeof probe === \"object\" && probe !== null ? probe as ChartCompositeProbeRecord : null;\n}\n\n/** True for an object shaped like an `ImageKernelAccelerator` (the handle form that shares a device). */\nfunction isAccelerator(value: unknown): boolean {\n return typeof value === \"object\" && value !== null && typeof (value as { convolveIrradiance?: unknown }).convolveIrradiance === \"function\" &&\n typeof (value as { backend?: unknown }).backend === \"string\";\n}\n\n/**\n * Internal (#481): opens the GPU session of a prepared view, or throws (`\"require\"`) when the GPU cannot be used. Called only\n * for `gpu: \"auto\" | \"require\"`.\n */\nexport async function openDisplayViewGpuSession(options: ParsedPrepareDisplayViewOptions, request: DisplayViewGpuRequest, signal: AbortSignal | undefined): Promise<DisplayViewGpuSession> {\n if (!getWebGpuEnabled()) return fallBack(options, \"webgpu-disabled\", \"WebGPU is switched off in this realm (setWebGpuEnabled(false)).\");\n const factory = displayViewGpuRendererFactory();\n if (!factory) return fallBack(options, \"unsupported-on-backend\", \"this version of the engine has no GPU display-view renderer (#478); no device was requested.\");\n // #563: the lens signal (projection, distortion, vignetting, rotation) runs on the CPU reference only; no device is requested for it.\n if (request.lens) return fallBack(options, \"unsupported-on-backend\", \"the GPU display-view renderers do not render lens.projection, lens.distortion, lens.vignetting or \" +\n \"camera rotation (#563); the CPU reference renders them. No device was requested.\");\n let runtime: WebGpuRuntime, owned = false;\n if (isAccelerator(options.gpuDevice)) {\n const shared = acceleratorRuntime(options.gpuDevice) as WebGpuRuntime | null | undefined;\n if (shared === undefined) throw new InvalidConfigurationError(\"prepareDisplayView options.gpuDevice must be an accelerator created by createImageKernelAccelerator.\");\n const accelerator = options.gpuDevice as { state: string; fallbackReason: DisplayViewGpuFallbackReason | null };\n if (accelerator.state === \"disposed\") throw new InvalidConfigurationError(\"prepareDisplayView options.gpuDevice is a disposed accelerator.\");\n if (shared === null) return fallBack(options, accelerator.fallbackReason ?? \"webgpu-unavailable\", \"the given accelerator runs the CPU reference and has no device.\");\n if (shared.isLost()) return fallBack(options, \"device-lost\", \"the given accelerator's device was lost.\", shared.adapter);\n runtime = shared;\n } else {\n const gpu = options.gpuDevice !== undefined ? options.gpuDevice : (globalThis as { navigator?: { gpu?: unknown } }).navigator?.gpu;\n let acquired: Awaited<ReturnType<typeof acquireWebGpuRuntime>>;\n try { acquired = await acquireWebGpuRuntime(gpu, undefined, signal); }\n catch (error) {\n if (error instanceof ImageKernelExecutionError && error.reason === \"aborted\") throw new InvalidConfigurationError(\"prepareDisplayView aborted.\");\n throw error;\n }\n if (\"failure\" in acquired) return fallBack(options, acquired.failure, acquired.message);\n runtime = acquired.runtime; owned = true;\n }\n const renderer = factory(runtime), supported = renderer.supports(request);\n if (supported !== true) {\n if (owned) runtime.destroy();\n return fallBack(options, \"unsupported-on-backend\", \"the GPU display-view renderer \\\"\" + renderer.id + \"\\\" does not support this request: \" + supported, runtime.adapter);\n }\n return createSession(options, runtime, owned, renderer);\n}\n\n// ---------------------------------------------------------------------------------------------------------------\n// Run-time conformance self-check.\n\n/** A fixed, seeded test image (mulberry32) for the built-in cases. */\nfunction seededSamples(count: number, seed: number): Float64Array {\n let a = seed >>> 0;\n const out = new Float64Array(count);\n for (let i = 0; i < count; i++) {\n a = (a + 0x6d2b79f5) >>> 0;\n let t = Math.imul(a ^ (a >>> 15), 1 | a);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n const u = ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n out[i] = u < 0.05 ? 0 : 10 ** (u * 6 - 3);\n }\n return out;\n}\n/** One convolution case: normalized Gaussian kernels of width `sigma` per patch, compared with the float64 reference within the a-priori bound. */\nfunction convolutionCase(id: string, width: number, height: number, radius: number, patchWidth: number, patchHeight: number, seed: number): DisplayViewGpuConformanceCase {\n return { id, async run(runtime, signal): Promise<true | string> {\n const size = 2 * radius + 1, taps = size * size, columns = Math.ceil(width / patchWidth), rows = Math.ceil(height / patchHeight);\n const kernels = new Float64Array(columns * rows * taps);\n for (let p = 0; p < columns * rows; p++) {\n const sigma = 0.6 + 0.4 * (p % 3), scale = 0.8 + 0.05 * p;\n let sum = 0;\n for (let v = -radius; v <= radius; v++) for (let u = -radius; u <= radius; u++) { const w = Math.exp(-0.5 * (u * u + v * v) / (sigma * sigma)); kernels[p * taps + (v + radius) * size + u + radius] = w; sum += w; }\n for (let t = 0; t < taps; t++) kernels[p * taps + t] = kernels[p * taps + t]! / sum * Math.min(1, scale);\n }\n const input: IrradianceConvolutionInput = { schemaVersion: \"0.1.0\", width, height, kernelRadius: radius, patchWidth, patchHeight, boundary: \"zero-outside-grid\",\n samples: seededSamples(width * height, seed), kernels };\n const plan = calculateIrradianceConvolutionPlan(input), reference = new Float64Array(width * height);\n convolveIrradianceRows(plan, input.samples, input.kernels, 0, height, reference);\n {\n const result = await convolveIrradianceOnRuntime(runtime, input, signal);\n const bound = result.execution.errorBound;\n if (!bound || bound.kind !== \"relative-to-reference\") return \"the convolution reported no relative bound.\";\n let worst = 0, worstIndex = -1;\n for (let i = 0; i < reference.length; i++) {\n const allowed = bound.relative * reference[i]! + bound.absolute, excess = Math.abs(result.values[i]! - reference[i]!) - allowed;\n if (excess > worst) { worst = excess; worstIndex = i; }\n }\n return worstIndex < 0 ? true : \"sample \" + worstIndex + \" differs from the reference by \" + Math.abs(result.values[worstIndex]! - reference[worstIndex]!) +\n \", more than the a-priori bound \" + (bound.relative * reference[worstIndex]! + bound.absolute) + \".\";\n }\n } };\n}\n/** The built-in cases, run on every device before its first display-view render: the existing convolution kernel on two small images. */\nexport const DISPLAY_VIEW_GPU_BUILT_IN_CASES: readonly DisplayViewGpuConformanceCase[] = Object.freeze([\n convolutionCase(\"image-kernel:convolution:16x12-r1\", 16, 12, 1, 16, 12, 481),\n convolutionCase(\"image-kernel:convolution:32x24-r3-patches\", 32, 24, 3, 16, 12, 4781)\n]);\n\nasync function runConformance(runtime: WebGpuRuntime, renderer: DisplayViewGpuRenderer, signal: AbortSignal | undefined): Promise<DisplayViewGpuConformance> {\n const cases = [...DISPLAY_VIEW_GPU_BUILT_IN_CASES, ...(renderer.conformanceCases ?? [])], ids = Object.freeze(cases.map((c) => c.id));\n for (const c of cases) {\n let outcome: true | string;\n try { outcome = await c.run(runtime, signal); }\n catch (error) {\n // An abort is the caller's, not the device's; everything else the device did wrong is a failed case.\n if (error instanceof ImageKernelExecutionError && error.reason === \"aborted\") throw error;\n outcome = \"the case threw \" + (error instanceof ImageKernelExecutionError ? error.reason + \": \" : \"\") + (error instanceof Error ? error.message : String(error));\n }\n if (outcome !== true) return Object.freeze({ cases: ids, passed: false, failedCase: c.id, detail: outcome });\n }\n return Object.freeze({ cases: ids, passed: true, failedCase: null, detail: null });\n}\n\n// ---------------------------------------------------------------------------------------------------------------\n\nfunction createSession(options: ParsedPrepareDisplayViewOptions, runtime: WebGpuRuntime, owned: boolean, renderer: DisplayViewGpuRenderer): DisplayViewGpuSession {\n const adapter = runtime.adapter;\n let disposed = false, lost = false, conformance: DisplayViewGpuConformance | null = null, checking: Promise<DisplayViewGpuConformance> | null = null;\n /** The last GPU turn: renders queue behind it, so one dispatch runs at a time on the device. */\n let tail: Promise<unknown> = Promise.resolve();\n /** A CPU fallback label for `\"auto\"`; with `\"require\"` the same event is an error. */\n const fallback = async (reason: DisplayViewGpuFallbackReason, detail: string, cpu: () => Promise<DisplayViewRenderResult>, compositeProbe: ChartCompositeProbeRecord | null = null):\n Promise<{ rendered: DisplayViewRenderResult; execution: DisplayViewExecution }> => {\n if (options.gpu === \"require\") throw requireError(reason, detail, compositeProbe);\n return { rendered: await cpu(), execution: cpuDisplayViewExecution(options.gpu, reason, adapter, conformance, detail, compositeProbe) };\n };\n /** The self-check, run once per session (single flight); a failing check is remembered and never repeated. */\n function selfCheck(signal: AbortSignal | undefined): Promise<DisplayViewGpuConformance> {\n if (conformance) return Promise.resolve(conformance);\n if (!checking) {\n checking = runConformance(runtime, renderer, signal).then((result) => { conformance = result; return result; }, (error: unknown) => { checking = null; throw error; });\n }\n return checking;\n }\n function lostError(error: unknown): boolean { return (error instanceof ImageKernelExecutionError && error.reason === \"device-lost\") || runtime.isLost(); }\n return {\n async render(setup, signal, cpu): Promise<{ rendered: DisplayViewRenderResult; execution: DisplayViewExecution }> {\n if (disposed) return fallback(\"disposed\", \"the prepared view was disposed.\", cpu);\n if (lost || runtime.isLost()) { lost = true; return fallback(\"device-lost\", \"the WebGPU device was lost; the rest of the view runs on the CPU.\", cpu); }\n let check: DisplayViewGpuConformance;\n try { check = await selfCheck(signal); }\n catch (error) {\n if (lostError(error)) { lost = true; return fallback(\"device-lost\", \"the WebGPU device was lost during its conformance check.\", cpu); }\n setup.checkAbort();\n throw error;\n }\n if (!check.passed) return fallback(\"conformance-failed\", \"the device failed conformance case \\\"\" + check.failedCase + \"\\\": \" + check.detail, cpu);\n const turn = tail.then(async () => {\n if (disposed || lost || runtime.isLost()) return null;\n setup.checkAbort();\n return renderer.render({ setup, signal });\n });\n tail = turn.catch(() => undefined);\n let output: Awaited<typeof turn>;\n try { output = await turn; }\n catch (error) {\n if (lostError(error)) { lost = true; return fallback(\"device-lost\", \"the WebGPU device was lost during a render; the rest of the view runs on the CPU.\", cpu); }\n setup.checkAbort();\n if (error instanceof ImageKernelExecutionError && error.reason === \"unsupported-on-backend\")\n return fallback(\"unsupported-on-backend\", \"the GPU display-view renderer \\\"\" + renderer.id + \"\\\" does not cover this render: \" + error.message, cpu, probeOf(error));\n // #492: a render past the device's limits (a kernel table or band above its storage binding limit) runs the CPU reference too.\n if (error instanceof ImageKernelExecutionError && error.reason === \"insufficient-limits\")\n return fallback(\"insufficient-limits\", \"the device's limits do not hold this render on the GPU: \" + error.message, cpu);\n throw error;\n }\n if (output === null) return this.render(setup, signal, cpu);\n const { errorBound, diagnosticUncertaintySampleCount: uncertainty = 0, compositeProbe = null, ...rendered } = output;\n const execution: DisplayViewExecution = Object.freeze({ gpu: options.gpu, backend: \"webgpu-f32\", requestedBackend: \"webgpu-f32\", fallbackReason: null, arithmetic: \"float32\",\n assurance: \"approximation-with-a-priori-bound\", fast: true, bitIdenticalToReference: false, errorBound, diagnosticsExact: uncertainty === 0,\n diagnosticUncertaintySampleCount: uncertainty, limitations: WEBGPU_F32_LIMITATIONS, adapter, conformance: check, compositeProbe });\n return { rendered, execution };\n },\n dispose(): void {\n if (disposed) return;\n disposed = true;\n renderer.dispose?.();\n if (owned) runtime.destroy();\n }\n };\n}\n"]}
1
+ {"version":3,"file":"display-view-gpu-session.js","sourceRoot":"","sources":["../../src/facade/display-view-gpu-session.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * #481: the device handling behind `prepareDisplayView(request, { gpu: \"auto\" | \"require\", gpuDevice })`. Loaded on demand by\n * `simulate-display-view.ts`, so the GPU code stays out of bundles that never ask for it. One session per prepared view:\n *\n * - the realm's switch (`setWebGpuEnabled(false)`) vetoes before anything else: `\"auto\"` falls back with `webgpu-disabled`,\n * `\"require\"` throws it;\n * - with no renderer registered (the engine registers its renderer, the Speed and Quality kernels of #478 and #479, when this module\n * loads; a caller may replace it or set null) no device is requested: `unsupported-on-backend`;\n * - the device is the handle's (`gpuDevice`: an `ImageKernelAccelerator`'s device, shared and left to its owner, or a WebGPU\n * entry point to acquire from), or acquired from `navigator.gpu` and owned by the session; the accelerator's acquisition\n * reasons apply, and the request's `signal` aborts the acquisition;\n * - the renderer must support the request, else `unsupported-on-backend`; a render the renderer refuses only when rendering\n * (`unsupported-on-backend` thrown by `render`: a coarse view, a device that fails the composite chart probe, #491) runs the\n * CPU reference for that render with the same label, and so does a render whose tables or bands exceed the device's limits\n * (`insufficient-limits` thrown by `render`: #492, a large defocus kernel's table on a scene of many materials);\n * - before the first GPU render on the device a short conformance self-check runs once (single-flight): the built-in cases run\n * the existing `webgpu-f32` convolution kernel against the float64 reference within its a-priori bound, then the renderer's own\n * cases; a failure keeps the whole view on the CPU, labelled `conformance-failed`, with the adapter recorded;\n * - GPU renders of one session run one at a time on the device (the accelerator's single flight; later renders wait);\n * - a lost device falls back to the CPU for that render and every later one, labelled `device-lost`; `dispose()` releases an\n * owned device, and later renders run on the CPU labelled `disposed`.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport { getWebGpuEnabled } from \"../gpu/webgpu-switch.js\";\nimport { acquireWebGpuRuntime, type WebGpuRuntime } from \"../gpu/webgpu-runtime.js\";\nimport { ImageKernelExecutionError, WEBGPU_F32_LIMITATIONS, type ChartCompositeProbeRecord, type ImageKernelAdapterDescription } from \"../gpu/image-kernel-execution.js\";\nimport { acceleratorRuntime, convolveIrradianceOnRuntime } from \"../gpu/image-kernel-accelerator.js\";\nimport { calculateIrradianceConvolutionPlan, convolveIrradianceRows, type IrradianceConvolutionInput } from \"../optics/irradiance-convolution.js\";\nimport type { DisplayViewRenderResult, DisplayViewSetup } from \"./display-view.js\";\nimport { displayViewGpuRendererFactory as engineDisplayViewGpuRendererFactory } from \"../gpu/display-view-quality-gpu.js\";\nimport { cpuDisplayViewExecution, displayViewGpuRendererFactory, setDisplayViewGpuRendererFactory, type DisplayViewExecution, type DisplayViewGpuConformance, type DisplayViewGpuConformanceCase,\n type DisplayViewGpuFallbackReason, type DisplayViewGpuRenderer, type DisplayViewGpuRequest, type ParsedPrepareDisplayViewOptions } from \"./display-view-gpu.js\";\n\n// #478, #479: the engine's own renderer, the display view's Speed and Quality kernels behind one renderer\n// (`src/gpu/display-view-quality-gpu.ts`), is registered when this module loads (that is, when a prepared view first asks for the\n// GPU) unless a caller registered a renderer before; a test that needs \"no renderer\" sets the factory to null.\nif (displayViewGpuRendererFactory() === null) setDisplayViewGpuRendererFactory(engineDisplayViewGpuRendererFactory);\n\n/** Internal: the GPU side of one prepared view. */\nexport interface DisplayViewGpuSession {\n /** Renders `setup` on the GPU when the session can, else through `cpu`; the label says which ran. */\n render(setup: DisplayViewSetup, signal: AbortSignal | undefined, cpu: () => Promise<DisplayViewRenderResult>): Promise<{ rendered: DisplayViewRenderResult; execution: DisplayViewExecution }>;\n dispose(): void;\n}\n\n/** A session that renders every view on the CPU with one fixed reason. */\nfunction cpuSession(options: ParsedPrepareDisplayViewOptions, reason: DisplayViewGpuFallbackReason, detail: string, adapter: ImageKernelAdapterDescription | null,\n conformance: DisplayViewGpuConformance | null): DisplayViewGpuSession {\n const execution = cpuDisplayViewExecution(options.gpu, reason, adapter, conformance, detail);\n return { async render(_setup, _signal, cpu): Promise<{ rendered: DisplayViewRenderResult; execution: DisplayViewExecution }> { return { rendered: await cpu(), execution }; },\n dispose(): void { /* nothing acquired */ } };\n}\n\n/** `\"require\"` throws the reason; `\"auto\"` gets a CPU session labelled with it. */\nfunction fallBack(options: ParsedPrepareDisplayViewOptions, reason: DisplayViewGpuFallbackReason, detail: string, adapter: ImageKernelAdapterDescription | null = null,\n conformance: DisplayViewGpuConformance | null = null): DisplayViewGpuSession {\n if (options.gpu === \"require\") throw requireError(reason, detail);\n return cpuSession(options, reason, detail, adapter, conformance);\n}\n/**\n * The error `\"require\"` throws instead of falling back. Every display-view fallback reason is also a failure reason of the accelerator's\n * error. A refusal by the composite chart probe carries its record as `probe` (the structured detail of the message).\n */\nfunction requireError(reason: DisplayViewGpuFallbackReason, detail: string, probe: ChartCompositeProbeRecord | null = null): ImageKernelExecutionError {\n const error = new ImageKernelExecutionError(reason, \"prepareDisplayView with gpu \\\"require\\\": \" + detail);\n if (probe) Object.defineProperty(error, \"probe\", { value: probe, enumerable: true });\n return error;\n}\n/** The composite chart probe's record on a refusal (`ChartCompositeProbeError.probe`), or null. */\nfunction probeOf(error: unknown): ChartCompositeProbeRecord | null {\n const probe = (error as { probe?: unknown }).probe;\n return typeof probe === \"object\" && probe !== null ? probe as ChartCompositeProbeRecord : null;\n}\n\n/** True for an object shaped like an `ImageKernelAccelerator` (the handle form that shares a device). */\nfunction isAccelerator(value: unknown): boolean {\n return typeof value === \"object\" && value !== null && typeof (value as { convolveIrradiance?: unknown }).convolveIrradiance === \"function\" &&\n typeof (value as { backend?: unknown }).backend === \"string\";\n}\n\n/**\n * Internal (#481): opens the GPU session of a prepared view, or throws (`\"require\"`) when the GPU cannot be used. Called only\n * for `gpu: \"auto\" | \"require\"`.\n */\nexport async function openDisplayViewGpuSession(options: ParsedPrepareDisplayViewOptions, request: DisplayViewGpuRequest, signal: AbortSignal | undefined): Promise<DisplayViewGpuSession> {\n if (!getWebGpuEnabled()) return fallBack(options, \"webgpu-disabled\", \"WebGPU is switched off in this realm (setWebGpuEnabled(false)).\");\n const factory = displayViewGpuRendererFactory();\n if (!factory) return fallBack(options, \"unsupported-on-backend\", \"this version of the engine has no GPU display-view renderer (#478); no device was requested.\");\n // #563: the lens signal (projection, distortion, vignetting, rotation) runs on the CPU reference only; no device is requested for it.\n if (request.lens) return fallBack(options, \"unsupported-on-backend\", \"the GPU display-view renderers do not render lens.projection, lens.distortion, lens.vignetting or \" +\n \"camera rotation (#563); the CPU reference renders them. No device was requested.\");\n if (request.mixedIllumination) return fallBack(options, \"unsupported-on-backend\", \"the GPU renderers light chart materials with one illuminant; the CPU reference renders mixed illumination (#550). No device was requested.\");\n let runtime: WebGpuRuntime, owned = false;\n if (isAccelerator(options.gpuDevice)) {\n const shared = acceleratorRuntime(options.gpuDevice) as WebGpuRuntime | null | undefined;\n if (shared === undefined) throw new InvalidConfigurationError(\"prepareDisplayView options.gpuDevice must be an accelerator created by createImageKernelAccelerator.\");\n const accelerator = options.gpuDevice as { state: string; fallbackReason: DisplayViewGpuFallbackReason | null };\n if (accelerator.state === \"disposed\") throw new InvalidConfigurationError(\"prepareDisplayView options.gpuDevice is a disposed accelerator.\");\n if (shared === null) return fallBack(options, accelerator.fallbackReason ?? \"webgpu-unavailable\", \"the given accelerator runs the CPU reference and has no device.\");\n if (shared.isLost()) return fallBack(options, \"device-lost\", \"the given accelerator's device was lost.\", shared.adapter);\n runtime = shared;\n } else {\n const gpu = options.gpuDevice !== undefined ? options.gpuDevice : (globalThis as { navigator?: { gpu?: unknown } }).navigator?.gpu;\n let acquired: Awaited<ReturnType<typeof acquireWebGpuRuntime>>;\n try { acquired = await acquireWebGpuRuntime(gpu, undefined, signal); }\n catch (error) {\n if (error instanceof ImageKernelExecutionError && error.reason === \"aborted\") throw new InvalidConfigurationError(\"prepareDisplayView aborted.\");\n throw error;\n }\n if (\"failure\" in acquired) return fallBack(options, acquired.failure, acquired.message);\n runtime = acquired.runtime; owned = true;\n }\n const renderer = factory(runtime), supported = renderer.supports(request);\n if (supported !== true) {\n if (owned) runtime.destroy();\n return fallBack(options, \"unsupported-on-backend\", \"the GPU display-view renderer \\\"\" + renderer.id + \"\\\" does not support this request: \" + supported, runtime.adapter);\n }\n return createSession(options, runtime, owned, renderer);\n}\n\n// ---------------------------------------------------------------------------------------------------------------\n// Run-time conformance self-check.\n\n/** A fixed, seeded test image (mulberry32) for the built-in cases. */\nfunction seededSamples(count: number, seed: number): Float64Array {\n let a = seed >>> 0;\n const out = new Float64Array(count);\n for (let i = 0; i < count; i++) {\n a = (a + 0x6d2b79f5) >>> 0;\n let t = Math.imul(a ^ (a >>> 15), 1 | a);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n const u = ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n out[i] = u < 0.05 ? 0 : 10 ** (u * 6 - 3);\n }\n return out;\n}\n/** One convolution case: normalized Gaussian kernels of width `sigma` per patch, compared with the float64 reference within the a-priori bound. */\nfunction convolutionCase(id: string, width: number, height: number, radius: number, patchWidth: number, patchHeight: number, seed: number): DisplayViewGpuConformanceCase {\n return { id, async run(runtime, signal): Promise<true | string> {\n const size = 2 * radius + 1, taps = size * size, columns = Math.ceil(width / patchWidth), rows = Math.ceil(height / patchHeight);\n const kernels = new Float64Array(columns * rows * taps);\n for (let p = 0; p < columns * rows; p++) {\n const sigma = 0.6 + 0.4 * (p % 3), scale = 0.8 + 0.05 * p;\n let sum = 0;\n for (let v = -radius; v <= radius; v++) for (let u = -radius; u <= radius; u++) { const w = Math.exp(-0.5 * (u * u + v * v) / (sigma * sigma)); kernels[p * taps + (v + radius) * size + u + radius] = w; sum += w; }\n for (let t = 0; t < taps; t++) kernels[p * taps + t] = kernels[p * taps + t]! / sum * Math.min(1, scale);\n }\n const input: IrradianceConvolutionInput = { schemaVersion: \"0.1.0\", width, height, kernelRadius: radius, patchWidth, patchHeight, boundary: \"zero-outside-grid\",\n samples: seededSamples(width * height, seed), kernels };\n const plan = calculateIrradianceConvolutionPlan(input), reference = new Float64Array(width * height);\n convolveIrradianceRows(plan, input.samples, input.kernels, 0, height, reference);\n {\n const result = await convolveIrradianceOnRuntime(runtime, input, signal);\n const bound = result.execution.errorBound;\n if (!bound || bound.kind !== \"relative-to-reference\") return \"the convolution reported no relative bound.\";\n let worst = 0, worstIndex = -1;\n for (let i = 0; i < reference.length; i++) {\n const allowed = bound.relative * reference[i]! + bound.absolute, excess = Math.abs(result.values[i]! - reference[i]!) - allowed;\n if (excess > worst) { worst = excess; worstIndex = i; }\n }\n return worstIndex < 0 ? true : \"sample \" + worstIndex + \" differs from the reference by \" + Math.abs(result.values[worstIndex]! - reference[worstIndex]!) +\n \", more than the a-priori bound \" + (bound.relative * reference[worstIndex]! + bound.absolute) + \".\";\n }\n } };\n}\n/** The built-in cases, run on every device before its first display-view render: the existing convolution kernel on two small images. */\nexport const DISPLAY_VIEW_GPU_BUILT_IN_CASES: readonly DisplayViewGpuConformanceCase[] = Object.freeze([\n convolutionCase(\"image-kernel:convolution:16x12-r1\", 16, 12, 1, 16, 12, 481),\n convolutionCase(\"image-kernel:convolution:32x24-r3-patches\", 32, 24, 3, 16, 12, 4781)\n]);\n\nasync function runConformance(runtime: WebGpuRuntime, renderer: DisplayViewGpuRenderer, signal: AbortSignal | undefined): Promise<DisplayViewGpuConformance> {\n const cases = [...DISPLAY_VIEW_GPU_BUILT_IN_CASES, ...(renderer.conformanceCases ?? [])], ids = Object.freeze(cases.map((c) => c.id));\n for (const c of cases) {\n let outcome: true | string;\n try { outcome = await c.run(runtime, signal); }\n catch (error) {\n // An abort is the caller's, not the device's; everything else the device did wrong is a failed case.\n if (error instanceof ImageKernelExecutionError && error.reason === \"aborted\") throw error;\n outcome = \"the case threw \" + (error instanceof ImageKernelExecutionError ? error.reason + \": \" : \"\") + (error instanceof Error ? error.message : String(error));\n }\n if (outcome !== true) return Object.freeze({ cases: ids, passed: false, failedCase: c.id, detail: outcome });\n }\n return Object.freeze({ cases: ids, passed: true, failedCase: null, detail: null });\n}\n\n// ---------------------------------------------------------------------------------------------------------------\n\nfunction createSession(options: ParsedPrepareDisplayViewOptions, runtime: WebGpuRuntime, owned: boolean, renderer: DisplayViewGpuRenderer): DisplayViewGpuSession {\n const adapter = runtime.adapter;\n let disposed = false, lost = false, conformance: DisplayViewGpuConformance | null = null, checking: Promise<DisplayViewGpuConformance> | null = null;\n /** The last GPU turn: renders queue behind it, so one dispatch runs at a time on the device. */\n let tail: Promise<unknown> = Promise.resolve();\n /** A CPU fallback label for `\"auto\"`; with `\"require\"` the same event is an error. */\n const fallback = async (reason: DisplayViewGpuFallbackReason, detail: string, cpu: () => Promise<DisplayViewRenderResult>, compositeProbe: ChartCompositeProbeRecord | null = null):\n Promise<{ rendered: DisplayViewRenderResult; execution: DisplayViewExecution }> => {\n if (options.gpu === \"require\") throw requireError(reason, detail, compositeProbe);\n return { rendered: await cpu(), execution: cpuDisplayViewExecution(options.gpu, reason, adapter, conformance, detail, compositeProbe) };\n };\n /** The self-check, run once per session (single flight); a failing check is remembered and never repeated. */\n function selfCheck(signal: AbortSignal | undefined): Promise<DisplayViewGpuConformance> {\n if (conformance) return Promise.resolve(conformance);\n if (!checking) {\n checking = runConformance(runtime, renderer, signal).then((result) => { conformance = result; return result; }, (error: unknown) => { checking = null; throw error; });\n }\n return checking;\n }\n function lostError(error: unknown): boolean { return (error instanceof ImageKernelExecutionError && error.reason === \"device-lost\") || runtime.isLost(); }\n return {\n async render(setup, signal, cpu): Promise<{ rendered: DisplayViewRenderResult; execution: DisplayViewExecution }> {\n if (disposed) return fallback(\"disposed\", \"the prepared view was disposed.\", cpu);\n if (lost || runtime.isLost()) { lost = true; return fallback(\"device-lost\", \"the WebGPU device was lost; the rest of the view runs on the CPU.\", cpu); }\n let check: DisplayViewGpuConformance;\n try { check = await selfCheck(signal); }\n catch (error) {\n if (lostError(error)) { lost = true; return fallback(\"device-lost\", \"the WebGPU device was lost during its conformance check.\", cpu); }\n setup.checkAbort();\n throw error;\n }\n if (!check.passed) return fallback(\"conformance-failed\", \"the device failed conformance case \\\"\" + check.failedCase + \"\\\": \" + check.detail, cpu);\n const turn = tail.then(async () => {\n if (disposed || lost || runtime.isLost()) return null;\n setup.checkAbort();\n return renderer.render({ setup, signal });\n });\n tail = turn.catch(() => undefined);\n let output: Awaited<typeof turn>;\n try { output = await turn; }\n catch (error) {\n if (lostError(error)) { lost = true; return fallback(\"device-lost\", \"the WebGPU device was lost during a render; the rest of the view runs on the CPU.\", cpu); }\n setup.checkAbort();\n if (error instanceof ImageKernelExecutionError && error.reason === \"unsupported-on-backend\")\n return fallback(\"unsupported-on-backend\", \"the GPU display-view renderer \\\"\" + renderer.id + \"\\\" does not cover this render: \" + error.message, cpu, probeOf(error));\n // #492: a render past the device's limits (a kernel table or band above its storage binding limit) runs the CPU reference too.\n if (error instanceof ImageKernelExecutionError && error.reason === \"insufficient-limits\")\n return fallback(\"insufficient-limits\", \"the device's limits do not hold this render on the GPU: \" + error.message, cpu);\n throw error;\n }\n if (output === null) return this.render(setup, signal, cpu);\n const { errorBound, diagnosticUncertaintySampleCount: uncertainty = 0, compositeProbe = null, ...rendered } = output;\n const execution: DisplayViewExecution = Object.freeze({ gpu: options.gpu, backend: \"webgpu-f32\", requestedBackend: \"webgpu-f32\", fallbackReason: null, arithmetic: \"float32\",\n assurance: \"approximation-with-a-priori-bound\", fast: true, bitIdenticalToReference: false, errorBound, diagnosticsExact: uncertainty === 0,\n diagnosticUncertaintySampleCount: uncertainty, limitations: WEBGPU_F32_LIMITATIONS, adapter, conformance: check, compositeProbe });\n return { rendered, execution };\n },\n dispose(): void {\n if (disposed) return;\n disposed = true;\n renderer.dispose?.();\n if (owned) runtime.destroy();\n }\n };\n}\n"]}
@@ -109,8 +109,13 @@ export interface DisplayViewGpuRequest {
109
109
  * renders it (display-view-lens-signal.ts) and no GPU renderer is asked or device requested (`unsupported-on-backend`).
110
110
  */
111
111
  lens?: boolean;
112
+ /**
113
+ * #550: true when the request has `illumination` (mixed lighting): the radiance at a point is no longer a function of its
114
+ * material, so the GPU material lookup cannot render it; the CPU reference does, exactly, and no device is requested.
115
+ */
116
+ mixedIllumination?: boolean;
112
117
  /** The scene's form: an engine chart, a declared `material-layers` scene (#491), or a caller function. */
113
- scene: "chart" | "material-layers" | "material-function" | "reflectance-function" | "radiance-function";
118
+ scene: "chart" | "material-layers" | "material-function" | "reflectance-function" | "radiance-function" | "image-plane";
114
119
  }
115
120
  /** One render of a region: the CPU renderer's own setup (tables, readout, demosaic, region, callbacks) and the render's signal. */
116
121
  export interface DisplayViewGpuPart {
@@ -1 +1 @@
1
- {"version":3,"file":"display-view-gpu.js","sourceRoot":"","sources":["../../src/facade/display-view-gpu.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * #481: how a prepared display view chooses between a WebGPU preview renderer and the CPU reference, and how a render labels\n * which ran. This module holds the option, the label and the renderer contract and imports nothing from the GPU code, so a\n * bundle that never asks for the GPU (`gpu: \"off\"`, the default) does not contain it; the device handling lives in\n * `display-view-gpu-session.ts`, loaded on demand by `prepareDisplayView` when `gpu` is `\"auto\"` or `\"require\"`.\n *\n * The vocabulary is the image-kernel accelerator's (`createImageKernelAccelerator`, docs/WEBGPU.md): `\"auto\"` is\n * `backend: \"webgpu-f32\"` with `fallback: \"cpu-reference\"`, `\"require\"` is `fallback: \"fail\"`, `\"off\"` is\n * `backend: \"cpu-reference\"`. The render's `diagnostics.fast.execution` names the backend that ran, the fallback reason and the\n * bound in the fields of `ImageKernelExecution`, plus the adapter and the run-time conformance check.\n *\n * No GPU display-view renderer exists yet (#478, #479): until one registers itself through {@link setDisplayViewGpuRendererFactory},\n * `\"auto\"` runs the CPU reference labelled `unsupported-on-backend` without touching a device, and `\"require\"` fails with that reason.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport type { ChartCompositeProbeRecord, ImageKernelAdapterDescription, ImageKernelBackend, ImageKernelExecution, ImageKernelFallbackReason } from \"../gpu/image-kernel-execution.js\";\nimport type { DisplayViewRenderResult, DisplayViewSetup } from \"./display-view.js\";\nimport type { SimulateCaptureFastReport } from \"./simulate-capture.js\";\n\n/**\n * 2.11 (#481): whether a prepared display view may render on the GPU. `\"off\"` (the default) is the CPU reference, today's\n * behaviour byte for byte. `\"auto\"` renders on WebGPU when a conforming device is available and the request is supported, and\n * otherwise runs the CPU reference and says why. `\"require\"` fails instead of falling back. In the accelerator's words: `\"auto\"`\n * is `backend: \"webgpu-f32\"` with `fallback: \"cpu-reference\"`, `\"require\"` is `fallback: \"fail\"`, `\"off\"` is `backend: \"cpu-reference\"`.\n */\nexport type DisplayViewGpuMode = \"off\" | \"auto\" | \"require\";\n\n/** 2.11 (#481): the second argument of `prepareDisplayView`. */\nexport interface PrepareDisplayViewOptions {\n /**\n * See {@link DisplayViewGpuMode}. 2.20.0: default `\"auto\"` when the request resolves to fast (`fast` omitted or true: the\n * display view's default) and `\"off\"` when it is exact (`fast: false`); an explicit value wins.\n */\n gpu?: DisplayViewGpuMode;\n /**\n * Where the device comes from, with `gpu: \"auto\"` or `\"require\"`: a WebGPU entry point (a worker's `navigator.gpu`), or an\n * `ImageKernelAccelerator` whose device the view shares (the accelerator keeps ownership; `dispose()` of the prepared view\n * leaves it alone). Without it the engine acquires a device from `globalThis.navigator.gpu` and owns it until `dispose()`.\n * Refused when `gpu` is or defaults to `\"off\"`.\n */\n gpuDevice?: unknown;\n}\n\n/** The parsed form of {@link PrepareDisplayViewOptions}. @internal */\nexport interface ParsedPrepareDisplayViewOptions { gpu: DisplayViewGpuMode; gpuDevice: unknown }\n\n/** Internal: validates the second argument of `prepareDisplayView`; `fast` is the request's resolved top-level fast (the GPU default). */\nexport function parsePrepareDisplayViewOptions(value: unknown, fast = false): ParsedPrepareDisplayViewOptions {\n if (value === undefined) value = {};\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) throw new InvalidConfigurationError(\"prepareDisplayView options must be an object { gpu, gpuDevice }.\");\n for (const key of Object.keys(value)) if (key !== \"gpu\" && key !== \"gpuDevice\") throw new InvalidConfigurationError(\"Unknown prepareDisplayView options field: \" + key + \".\");\n const { gpu, gpuDevice } = value as Record<string, unknown>;\n const mode: DisplayViewGpuMode = gpu === undefined ? fast ? \"auto\" : \"off\" : gpu as DisplayViewGpuMode;\n if (mode !== \"off\" && mode !== \"auto\" && mode !== \"require\") throw new InvalidConfigurationError(\"prepareDisplayView options.gpu must be \\\"off\\\", \\\"auto\\\" or \\\"require\\\".\");\n if (gpuDevice !== undefined && (typeof gpuDevice !== \"object\" || gpuDevice === null)) throw new InvalidConfigurationError(\"prepareDisplayView options.gpuDevice must be a WebGPU entry point (navigator.gpu) or an ImageKernelAccelerator.\");\n if (gpuDevice !== undefined && mode === \"off\") throw new InvalidConfigurationError(\"prepareDisplayView options.gpuDevice needs gpu \\\"auto\\\" or \\\"require\\\".\");\n return { gpu: mode, gpuDevice };\n}\n\n/**\n * 2.11 (#481): why a display view that asked for the GPU (`gpu: \"auto\"`) ran the CPU reference. The accelerator's acquisition\n * reasons, plus: `unsupported-on-backend` (no GPU display-view renderer exists in this version, or it does not support the\n * request), `conformance-failed` (the device failed the run-time self-check before the view's first GPU render), `device-lost`\n * (the device was lost; the rest of the view runs on the CPU) and `disposed` (the prepared view was disposed).\n */\nexport type DisplayViewGpuFallbackReason = ImageKernelFallbackReason | \"unsupported-on-backend\" | \"conformance-failed\" | \"device-lost\" | \"disposed\";\n\n/** 2.11 (#481): the run-time conformance self-check of a device, run once before the view's first GPU render. */\nexport interface DisplayViewGpuConformance {\n /** The ids of the cases run, in order (the built-in image-kernel cases, then the renderer's own). */\n cases: readonly string[];\n passed: boolean;\n /** The first case that failed, or null. */\n failedCase: string | null;\n /** What the failed case reported, or null. */\n detail: string | null;\n}\n\n/**\n * 2.11 (#481): where a display view's render ran, in the words of the image-kernel execution record (`ImageKernelExecution`):\n * `backend` names the path that ran (`cpu-reference`, the float64 engine reference, or `webgpu-f32`, a float32 approximation\n * within `errorBound`), `requestedBackend` what `gpu` asked for, and `fallbackReason` why a request for the GPU ran the CPU.\n * `adapter` describes the device's adapter whenever one was involved, also when the view then fell back; `conformance` is\n * the device's self-check once it has run. A CPU render keeps `assurance: \"engine-reference\"` and `fast: false`.\n */\nexport interface DisplayViewExecution extends Omit<ImageKernelExecution, \"fallbackReason\"> {\n /** The `gpu` option the view was prepared with. */\n gpu: DisplayViewGpuMode;\n fallbackReason: DisplayViewGpuFallbackReason | null;\n adapter: ImageKernelAdapterDescription | null;\n conformance: DisplayViewGpuConformance | null;\n /**\n * 2.11: the composite chart kernel's device probe when this render needed it (composite charts, the 2.3 elements and\n * `material-layers` scenes): the device class and the product path the kernel ran with, or, on a refusal (`fallbackReason`\n * `unsupported-on-backend`), why. Null when the render did not run the probe (the 2.0 presets, `gpu: \"off\"`).\n */\n compositeProbe: ChartCompositeProbeRecord | null;\n}\n\n/** 2.11 (#481): `diagnostics.fast` of a display view: the capture's report plus where the render ran. */\nexport interface DisplayViewFastReport extends SimulateCaptureFastReport {\n /** Where this render ran (see {@link DisplayViewExecution}). `assurance` above follows it. */\n execution: DisplayViewExecution;\n}\n\nconst CPU_LIMITATIONS = /* @__PURE__ */ Object.freeze([\"Float64 engine reference execution; results are the reference by definition\"]);\n\n/** Internal: the execution record of a display view rendered on the CPU reference. `requested` names what `gpu` asked for. */\nexport function cpuDisplayViewExecution(gpu: DisplayViewGpuMode, fallbackReason: DisplayViewGpuFallbackReason | null, adapter: ImageKernelAdapterDescription | null,\n conformance: DisplayViewGpuConformance | null, detail?: string, compositeProbe: ChartCompositeProbeRecord | null = null): DisplayViewExecution {\n const requestedBackend: ImageKernelBackend = gpu === \"off\" ? \"cpu-reference\" : \"webgpu-f32\";\n const limitations = detail === undefined ? CPU_LIMITATIONS : Object.freeze([...CPU_LIMITATIONS, \"WebGPU was requested (gpu: \\\"\" + gpu + \"\\\") and the CPU reference ran: \" + detail]);\n return Object.freeze({ gpu, backend: \"cpu-reference\", requestedBackend, fallbackReason, arithmetic: \"float64\", assurance: \"engine-reference\", fast: false,\n bitIdenticalToReference: true, errorBound: null, diagnosticsExact: true, diagnosticUncertaintySampleCount: 0, limitations, adapter, conformance, compositeProbe });\n}\n\n// ---------------------------------------------------------------------------------------------------------------\n// The renderer contract (#478 implements it; until then the only implementation is a test fake).\n\n/**\n * Internal (#481): the device a renderer or conformance case runs on. It is the engine's `WebGpuRuntime` object\n * (`src/gpu/webgpu-runtime.ts`: `device`, `guard`, `destroy` and the rest), seen here through its WebGPU-free members only so\n * that no WebGPU type reaches the published declarations (docs/WEBGPU.md); a renderer in the engine casts it to `WebGpuRuntime`.\n */\nexport interface DisplayViewGpuRuntimeHandle {\n readonly adapter: ImageKernelAdapterDescription | null;\n readonly maximumStorageBindingBytes: number;\n readonly maximumWorkgroupsPerDimension: number;\n isLost(): boolean;\n}\n\n/** What a prepared request asks of a GPU renderer (`supports`): the options that shape a render. */\nexport interface DisplayViewGpuRequest {\n ahd: boolean;\n diffraction: boolean;\n antiAliasing: boolean;\n /** Pixel-aperture samples per axis (1: centre sampling). */\n boxSamples: number;\n toneCurve: \"identity\" | \"positive-reinhard-per-channel\";\n /**\n * #492: true when `lens.defocus` needs the defocus disc (out of focus): the expected signal then carries the disc, or each\n * node's diffraction kernel convolved with it, as site kernels (#492 step 2b), which the engine's renderer gathers in its\n * Quality site pass (step 2c). Absent or false otherwise.\n */\n defocus?: boolean;\n /**\n * #564: true when the defocus kernel's radius is above 64 sites, so the expected signal convolves it by runs on the CPU\n * (`largeKernel`); no GPU renderer takes it. Absent or false otherwise.\n */\n largeDefocus?: boolean;\n /**\n * #563: true when the request has `lens.projection`, `lens.distortion`, `lens.vignetting` or camera rotation: the CPU reference\n * renders it (display-view-lens-signal.ts) and no GPU renderer is asked or device requested (`unsupported-on-backend`).\n */\n lens?: boolean;\n /** The scene's form: an engine chart, a declared `material-layers` scene (#491), or a caller function. */\n scene: \"chart\" | \"material-layers\" | \"material-function\" | \"reflectance-function\" | \"radiance-function\";\n}\n/** One render of a region: the CPU renderer's own setup (tables, readout, demosaic, region, callbacks) and the render's signal. */\nexport interface DisplayViewGpuPart { setup: DisplayViewSetup; signal: AbortSignal | undefined }\n/** What a GPU render returns: the CPU renderer's result shape plus the a-priori bound of its values against the reference. */\nexport interface DisplayViewGpuRenderOutput extends DisplayViewRenderResult {\n errorBound: NonNullable<ImageKernelExecution[\"errorBound\"]>;\n /** Samples whose float32 classification fell inside its bound (0 when none). */\n diagnosticUncertaintySampleCount?: number;\n /** The composite chart kernel's device probe record, when the render used the composite material module. */\n compositeProbe?: ChartCompositeProbeRecord;\n}\n/** A conformance case: returns `true` when the device agrees with the reference within the case's bound, or a sentence saying how it did not. */\nexport interface DisplayViewGpuConformanceCase { id: string; run(runtime: DisplayViewGpuRuntimeHandle, signal: AbortSignal | undefined): Promise<true | string> }\n/**\n * Internal (#481): the contract a GPU display-view renderer fulfils (#478). One instance serves one device, created by the\n * registered factory for each prepared view that acquires or shares a device. `supports` says whether the renderer covers a\n * prepared request (`true`) or why not (a sentence; the view then runs the CPU reference labelled `unsupported-on-backend`).\n * `render` renders one region on the device and must throw `ImageKernelExecutionError` with reason `device-lost` or `aborted`\n * for those two events, as the accelerator's operations do; a render that throws `unsupported-on-backend` (a request the\n * renderer finds it does not cover only when rendering) runs the CPU reference labelled with that reason, or fails with it under\n * `\"require\"`. `conformanceCases` are run after the built-in image-kernel cases before the device's first render; a failure keeps\n * the whole view on the CPU. `dispose` releases what the renderer holds on the device (#491: uploaded scene records); the session\n * calls it when the prepared view is disposed.\n */\nexport interface DisplayViewGpuRenderer {\n readonly id: string;\n supports(request: DisplayViewGpuRequest): true | string;\n render(part: DisplayViewGpuPart): Promise<DisplayViewGpuRenderOutput>;\n readonly conformanceCases?: readonly DisplayViewGpuConformanceCase[];\n dispose?(): void;\n}\nexport type DisplayViewGpuRendererFactory = (runtime: DisplayViewGpuRuntimeHandle) => DisplayViewGpuRenderer;\n\nlet rendererFactory: DisplayViewGpuRendererFactory | null = null;\n/**\n * Internal (#481): registers the renderer that `prepareDisplayView` uses for `gpu: \"auto\" | \"require\"`, and returns the one\n * registered before (null: none). #478's renderer registers itself here; tests register a fake. With none registered no device\n * is requested and every GPU request falls back (or fails) with `unsupported-on-backend`.\n */\nexport function setDisplayViewGpuRendererFactory(factory: DisplayViewGpuRendererFactory | null): DisplayViewGpuRendererFactory | null {\n if (factory !== null && typeof factory !== \"function\") throw new InvalidConfigurationError(\"setDisplayViewGpuRendererFactory expects a function or null.\");\n const previous = rendererFactory;\n rendererFactory = factory;\n return previous;\n}\n/** Internal: the registered factory. */\nexport function displayViewGpuRendererFactory(): DisplayViewGpuRendererFactory | null { return rendererFactory; }\n"]}
1
+ {"version":3,"file":"display-view-gpu.js","sourceRoot":"","sources":["../../src/facade/display-view-gpu.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * #481: how a prepared display view chooses between a WebGPU preview renderer and the CPU reference, and how a render labels\n * which ran. This module holds the option, the label and the renderer contract and imports nothing from the GPU code, so a\n * bundle that never asks for the GPU (`gpu: \"off\"`, the default) does not contain it; the device handling lives in\n * `display-view-gpu-session.ts`, loaded on demand by `prepareDisplayView` when `gpu` is `\"auto\"` or `\"require\"`.\n *\n * The vocabulary is the image-kernel accelerator's (`createImageKernelAccelerator`, docs/WEBGPU.md): `\"auto\"` is\n * `backend: \"webgpu-f32\"` with `fallback: \"cpu-reference\"`, `\"require\"` is `fallback: \"fail\"`, `\"off\"` is\n * `backend: \"cpu-reference\"`. The render's `diagnostics.fast.execution` names the backend that ran, the fallback reason and the\n * bound in the fields of `ImageKernelExecution`, plus the adapter and the run-time conformance check.\n *\n * No GPU display-view renderer exists yet (#478, #479): until one registers itself through {@link setDisplayViewGpuRendererFactory},\n * `\"auto\"` runs the CPU reference labelled `unsupported-on-backend` without touching a device, and `\"require\"` fails with that reason.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport type { ChartCompositeProbeRecord, ImageKernelAdapterDescription, ImageKernelBackend, ImageKernelExecution, ImageKernelFallbackReason } from \"../gpu/image-kernel-execution.js\";\nimport type { DisplayViewRenderResult, DisplayViewSetup } from \"./display-view.js\";\nimport type { SimulateCaptureFastReport } from \"./simulate-capture.js\";\n\n/**\n * 2.11 (#481): whether a prepared display view may render on the GPU. `\"off\"` (the default) is the CPU reference, today's\n * behaviour byte for byte. `\"auto\"` renders on WebGPU when a conforming device is available and the request is supported, and\n * otherwise runs the CPU reference and says why. `\"require\"` fails instead of falling back. In the accelerator's words: `\"auto\"`\n * is `backend: \"webgpu-f32\"` with `fallback: \"cpu-reference\"`, `\"require\"` is `fallback: \"fail\"`, `\"off\"` is `backend: \"cpu-reference\"`.\n */\nexport type DisplayViewGpuMode = \"off\" | \"auto\" | \"require\";\n\n/** 2.11 (#481): the second argument of `prepareDisplayView`. */\nexport interface PrepareDisplayViewOptions {\n /**\n * See {@link DisplayViewGpuMode}. 2.20.0: default `\"auto\"` when the request resolves to fast (`fast` omitted or true: the\n * display view's default) and `\"off\"` when it is exact (`fast: false`); an explicit value wins.\n */\n gpu?: DisplayViewGpuMode;\n /**\n * Where the device comes from, with `gpu: \"auto\"` or `\"require\"`: a WebGPU entry point (a worker's `navigator.gpu`), or an\n * `ImageKernelAccelerator` whose device the view shares (the accelerator keeps ownership; `dispose()` of the prepared view\n * leaves it alone). Without it the engine acquires a device from `globalThis.navigator.gpu` and owns it until `dispose()`.\n * Refused when `gpu` is or defaults to `\"off\"`.\n */\n gpuDevice?: unknown;\n}\n\n/** The parsed form of {@link PrepareDisplayViewOptions}. @internal */\nexport interface ParsedPrepareDisplayViewOptions { gpu: DisplayViewGpuMode; gpuDevice: unknown }\n\n/** Internal: validates the second argument of `prepareDisplayView`; `fast` is the request's resolved top-level fast (the GPU default). */\nexport function parsePrepareDisplayViewOptions(value: unknown, fast = false): ParsedPrepareDisplayViewOptions {\n if (value === undefined) value = {};\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) throw new InvalidConfigurationError(\"prepareDisplayView options must be an object { gpu, gpuDevice }.\");\n for (const key of Object.keys(value)) if (key !== \"gpu\" && key !== \"gpuDevice\") throw new InvalidConfigurationError(\"Unknown prepareDisplayView options field: \" + key + \".\");\n const { gpu, gpuDevice } = value as Record<string, unknown>;\n const mode: DisplayViewGpuMode = gpu === undefined ? fast ? \"auto\" : \"off\" : gpu as DisplayViewGpuMode;\n if (mode !== \"off\" && mode !== \"auto\" && mode !== \"require\") throw new InvalidConfigurationError(\"prepareDisplayView options.gpu must be \\\"off\\\", \\\"auto\\\" or \\\"require\\\".\");\n if (gpuDevice !== undefined && (typeof gpuDevice !== \"object\" || gpuDevice === null)) throw new InvalidConfigurationError(\"prepareDisplayView options.gpuDevice must be a WebGPU entry point (navigator.gpu) or an ImageKernelAccelerator.\");\n if (gpuDevice !== undefined && mode === \"off\") throw new InvalidConfigurationError(\"prepareDisplayView options.gpuDevice needs gpu \\\"auto\\\" or \\\"require\\\".\");\n return { gpu: mode, gpuDevice };\n}\n\n/**\n * 2.11 (#481): why a display view that asked for the GPU (`gpu: \"auto\"`) ran the CPU reference. The accelerator's acquisition\n * reasons, plus: `unsupported-on-backend` (no GPU display-view renderer exists in this version, or it does not support the\n * request), `conformance-failed` (the device failed the run-time self-check before the view's first GPU render), `device-lost`\n * (the device was lost; the rest of the view runs on the CPU) and `disposed` (the prepared view was disposed).\n */\nexport type DisplayViewGpuFallbackReason = ImageKernelFallbackReason | \"unsupported-on-backend\" | \"conformance-failed\" | \"device-lost\" | \"disposed\";\n\n/** 2.11 (#481): the run-time conformance self-check of a device, run once before the view's first GPU render. */\nexport interface DisplayViewGpuConformance {\n /** The ids of the cases run, in order (the built-in image-kernel cases, then the renderer's own). */\n cases: readonly string[];\n passed: boolean;\n /** The first case that failed, or null. */\n failedCase: string | null;\n /** What the failed case reported, or null. */\n detail: string | null;\n}\n\n/**\n * 2.11 (#481): where a display view's render ran, in the words of the image-kernel execution record (`ImageKernelExecution`):\n * `backend` names the path that ran (`cpu-reference`, the float64 engine reference, or `webgpu-f32`, a float32 approximation\n * within `errorBound`), `requestedBackend` what `gpu` asked for, and `fallbackReason` why a request for the GPU ran the CPU.\n * `adapter` describes the device's adapter whenever one was involved, also when the view then fell back; `conformance` is\n * the device's self-check once it has run. A CPU render keeps `assurance: \"engine-reference\"` and `fast: false`.\n */\nexport interface DisplayViewExecution extends Omit<ImageKernelExecution, \"fallbackReason\"> {\n /** The `gpu` option the view was prepared with. */\n gpu: DisplayViewGpuMode;\n fallbackReason: DisplayViewGpuFallbackReason | null;\n adapter: ImageKernelAdapterDescription | null;\n conformance: DisplayViewGpuConformance | null;\n /**\n * 2.11: the composite chart kernel's device probe when this render needed it (composite charts, the 2.3 elements and\n * `material-layers` scenes): the device class and the product path the kernel ran with, or, on a refusal (`fallbackReason`\n * `unsupported-on-backend`), why. Null when the render did not run the probe (the 2.0 presets, `gpu: \"off\"`).\n */\n compositeProbe: ChartCompositeProbeRecord | null;\n}\n\n/** 2.11 (#481): `diagnostics.fast` of a display view: the capture's report plus where the render ran. */\nexport interface DisplayViewFastReport extends SimulateCaptureFastReport {\n /** Where this render ran (see {@link DisplayViewExecution}). `assurance` above follows it. */\n execution: DisplayViewExecution;\n}\n\nconst CPU_LIMITATIONS = /* @__PURE__ */ Object.freeze([\"Float64 engine reference execution; results are the reference by definition\"]);\n\n/** Internal: the execution record of a display view rendered on the CPU reference. `requested` names what `gpu` asked for. */\nexport function cpuDisplayViewExecution(gpu: DisplayViewGpuMode, fallbackReason: DisplayViewGpuFallbackReason | null, adapter: ImageKernelAdapterDescription | null,\n conformance: DisplayViewGpuConformance | null, detail?: string, compositeProbe: ChartCompositeProbeRecord | null = null): DisplayViewExecution {\n const requestedBackend: ImageKernelBackend = gpu === \"off\" ? \"cpu-reference\" : \"webgpu-f32\";\n const limitations = detail === undefined ? CPU_LIMITATIONS : Object.freeze([...CPU_LIMITATIONS, \"WebGPU was requested (gpu: \\\"\" + gpu + \"\\\") and the CPU reference ran: \" + detail]);\n return Object.freeze({ gpu, backend: \"cpu-reference\", requestedBackend, fallbackReason, arithmetic: \"float64\", assurance: \"engine-reference\", fast: false,\n bitIdenticalToReference: true, errorBound: null, diagnosticsExact: true, diagnosticUncertaintySampleCount: 0, limitations, adapter, conformance, compositeProbe });\n}\n\n// ---------------------------------------------------------------------------------------------------------------\n// The renderer contract (#478 implements it; until then the only implementation is a test fake).\n\n/**\n * Internal (#481): the device a renderer or conformance case runs on. It is the engine's `WebGpuRuntime` object\n * (`src/gpu/webgpu-runtime.ts`: `device`, `guard`, `destroy` and the rest), seen here through its WebGPU-free members only so\n * that no WebGPU type reaches the published declarations (docs/WEBGPU.md); a renderer in the engine casts it to `WebGpuRuntime`.\n */\nexport interface DisplayViewGpuRuntimeHandle {\n readonly adapter: ImageKernelAdapterDescription | null;\n readonly maximumStorageBindingBytes: number;\n readonly maximumWorkgroupsPerDimension: number;\n isLost(): boolean;\n}\n\n/** What a prepared request asks of a GPU renderer (`supports`): the options that shape a render. */\nexport interface DisplayViewGpuRequest {\n ahd: boolean;\n diffraction: boolean;\n antiAliasing: boolean;\n /** Pixel-aperture samples per axis (1: centre sampling). */\n boxSamples: number;\n toneCurve: \"identity\" | \"positive-reinhard-per-channel\";\n /**\n * #492: true when `lens.defocus` needs the defocus disc (out of focus): the expected signal then carries the disc, or each\n * node's diffraction kernel convolved with it, as site kernels (#492 step 2b), which the engine's renderer gathers in its\n * Quality site pass (step 2c). Absent or false otherwise.\n */\n defocus?: boolean;\n /**\n * #564: true when the defocus kernel's radius is above 64 sites, so the expected signal convolves it by runs on the CPU\n * (`largeKernel`); no GPU renderer takes it. Absent or false otherwise.\n */\n largeDefocus?: boolean;\n /**\n * #563: true when the request has `lens.projection`, `lens.distortion`, `lens.vignetting` or camera rotation: the CPU reference\n * renders it (display-view-lens-signal.ts) and no GPU renderer is asked or device requested (`unsupported-on-backend`).\n */\n lens?: boolean;\n /**\n * #550: true when the request has `illumination` (mixed lighting): the radiance at a point is no longer a function of its\n * material, so the GPU material lookup cannot render it; the CPU reference does, exactly, and no device is requested.\n */\n mixedIllumination?: boolean;\n /** The scene's form: an engine chart, a declared `material-layers` scene (#491), or a caller function. */\n scene: \"chart\" | \"material-layers\" | \"material-function\" | \"reflectance-function\" | \"radiance-function\" | \"image-plane\";\n}\n/** One render of a region: the CPU renderer's own setup (tables, readout, demosaic, region, callbacks) and the render's signal. */\nexport interface DisplayViewGpuPart { setup: DisplayViewSetup; signal: AbortSignal | undefined }\n/** What a GPU render returns: the CPU renderer's result shape plus the a-priori bound of its values against the reference. */\nexport interface DisplayViewGpuRenderOutput extends DisplayViewRenderResult {\n errorBound: NonNullable<ImageKernelExecution[\"errorBound\"]>;\n /** Samples whose float32 classification fell inside its bound (0 when none). */\n diagnosticUncertaintySampleCount?: number;\n /** The composite chart kernel's device probe record, when the render used the composite material module. */\n compositeProbe?: ChartCompositeProbeRecord;\n}\n/** A conformance case: returns `true` when the device agrees with the reference within the case's bound, or a sentence saying how it did not. */\nexport interface DisplayViewGpuConformanceCase { id: string; run(runtime: DisplayViewGpuRuntimeHandle, signal: AbortSignal | undefined): Promise<true | string> }\n/**\n * Internal (#481): the contract a GPU display-view renderer fulfils (#478). One instance serves one device, created by the\n * registered factory for each prepared view that acquires or shares a device. `supports` says whether the renderer covers a\n * prepared request (`true`) or why not (a sentence; the view then runs the CPU reference labelled `unsupported-on-backend`).\n * `render` renders one region on the device and must throw `ImageKernelExecutionError` with reason `device-lost` or `aborted`\n * for those two events, as the accelerator's operations do; a render that throws `unsupported-on-backend` (a request the\n * renderer finds it does not cover only when rendering) runs the CPU reference labelled with that reason, or fails with it under\n * `\"require\"`. `conformanceCases` are run after the built-in image-kernel cases before the device's first render; a failure keeps\n * the whole view on the CPU. `dispose` releases what the renderer holds on the device (#491: uploaded scene records); the session\n * calls it when the prepared view is disposed.\n */\nexport interface DisplayViewGpuRenderer {\n readonly id: string;\n supports(request: DisplayViewGpuRequest): true | string;\n render(part: DisplayViewGpuPart): Promise<DisplayViewGpuRenderOutput>;\n readonly conformanceCases?: readonly DisplayViewGpuConformanceCase[];\n dispose?(): void;\n}\nexport type DisplayViewGpuRendererFactory = (runtime: DisplayViewGpuRuntimeHandle) => DisplayViewGpuRenderer;\n\nlet rendererFactory: DisplayViewGpuRendererFactory | null = null;\n/**\n * Internal (#481): registers the renderer that `prepareDisplayView` uses for `gpu: \"auto\" | \"require\"`, and returns the one\n * registered before (null: none). #478's renderer registers itself here; tests register a fake. With none registered no device\n * is requested and every GPU request falls back (or fails) with `unsupported-on-backend`.\n */\nexport function setDisplayViewGpuRendererFactory(factory: DisplayViewGpuRendererFactory | null): DisplayViewGpuRendererFactory | null {\n if (factory !== null && typeof factory !== \"function\") throw new InvalidConfigurationError(\"setDisplayViewGpuRendererFactory expects a function or null.\");\n const previous = rendererFactory;\n rendererFactory = factory;\n return previous;\n}\n/** Internal: the registered factory. */\nexport function displayViewGpuRendererFactory(): DisplayViewGpuRendererFactory | null { return rendererFactory; }\n"]}