@photivra/engine 2.9.0 → 2.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/CHANGELOG.md +223 -1
  2. package/CITATION.cff +1 -1
  3. package/NODE_SUPPORT.md +21 -3
  4. package/README.md +6 -6
  5. package/SECURITY.md +1 -1
  6. package/THIRD_PARTY.md +2 -0
  7. package/dist/capture/native-environment-lean.js +89 -5
  8. package/dist/capture/native-environment-lean.js.map +1 -1
  9. package/dist/capture/native-environment-tabulated.d.ts +37 -0
  10. package/dist/capture/native-environment-tabulated.js +42 -6
  11. package/dist/capture/native-environment-tabulated.js.map +1 -1
  12. package/dist/core/portable-math.d.ts +19 -0
  13. package/dist/core/portable-math.js +82 -0
  14. package/dist/core/portable-math.js.map +1 -1
  15. package/dist/core/version.d.ts +1 -1
  16. package/dist/core/version.js +1 -1
  17. package/dist/core/version.js.map +1 -1
  18. package/dist/facade/channel-response.d.ts +15 -0
  19. package/dist/facade/channel-response.js +33 -0
  20. package/dist/facade/channel-response.js.map +1 -0
  21. package/dist/facade/chart-material-layers.d.ts +115 -0
  22. package/dist/facade/chart-material-layers.js +224 -0
  23. package/dist/facade/chart-material-layers.js.map +1 -0
  24. package/dist/facade/chart-radiance-batch.d.ts +8 -2
  25. package/dist/facade/chart-radiance-batch.js +11 -4
  26. package/dist/facade/chart-radiance-batch.js.map +1 -1
  27. package/dist/facade/chart-scenes.d.ts +134 -0
  28. package/dist/facade/chart-scenes.js +32 -22
  29. package/dist/facade/chart-scenes.js.map +1 -1
  30. package/dist/facade/diffraction-provider.d.ts +8 -2
  31. package/dist/facade/diffraction-provider.js +120 -16
  32. package/dist/facade/diffraction-provider.js.map +1 -1
  33. package/dist/facade/display-view-gpu-session.d.ts +18 -0
  34. package/dist/facade/display-view-gpu-session.js +280 -0
  35. package/dist/facade/display-view-gpu-session.js.map +1 -0
  36. package/dist/facade/display-view-gpu.d.ts +146 -0
  37. package/dist/facade/display-view-gpu.js +59 -0
  38. package/dist/facade/display-view-gpu.js.map +1 -0
  39. package/dist/facade/display-view.d.ts +123 -1
  40. package/dist/facade/display-view.js +478 -116
  41. package/dist/facade/display-view.js.map +1 -1
  42. package/dist/facade/expected-signal-setup.d.ts +5 -0
  43. package/dist/facade/expected-signal-setup.js +18 -1
  44. package/dist/facade/expected-signal-setup.js.map +1 -1
  45. package/dist/facade/expected-signal.d.ts +80 -6
  46. package/dist/facade/expected-signal.js +200 -24
  47. package/dist/facade/expected-signal.js.map +1 -1
  48. package/dist/facade/scene-radiance.d.ts +4 -2
  49. package/dist/facade/scene-radiance.js +7 -4
  50. package/dist/facade/scene-radiance.js.map +1 -1
  51. package/dist/facade/simulate-capture.d.ts +81 -7
  52. package/dist/facade/simulate-capture.js +276 -53
  53. package/dist/facade/simulate-capture.js.map +1 -1
  54. package/dist/facade/simulate-display-view.d.ts +54 -3
  55. package/dist/facade/simulate-display-view.js +120 -27
  56. package/dist/facade/simulate-display-view.js.map +1 -1
  57. package/dist/gpu/chart-composite-gpu.d.ts +119 -0
  58. package/dist/gpu/chart-composite-gpu.js +572 -0
  59. package/dist/gpu/chart-composite-gpu.js.map +1 -0
  60. package/dist/gpu/chart-radiance-gpu.d.ts +6 -6
  61. package/dist/gpu/chart-radiance-gpu.js +9 -11
  62. package/dist/gpu/chart-radiance-gpu.js.map +1 -1
  63. package/dist/gpu/display-view-chart-material-module.d.ts +10 -0
  64. package/dist/gpu/display-view-chart-material-module.js +58 -0
  65. package/dist/gpu/display-view-chart-material-module.js.map +1 -0
  66. package/dist/gpu/display-view-composite-material-module.d.ts +68 -0
  67. package/dist/gpu/display-view-composite-material-module.js +248 -0
  68. package/dist/gpu/display-view-composite-material-module.js.map +1 -0
  69. package/dist/gpu/display-view-quality-gpu.d.ts +185 -0
  70. package/dist/gpu/display-view-quality-gpu.js +1000 -0
  71. package/dist/gpu/display-view-quality-gpu.js.map +1 -0
  72. package/dist/gpu/display-view-speed-gpu.d.ts +156 -0
  73. package/dist/gpu/display-view-speed-gpu.js +524 -0
  74. package/dist/gpu/display-view-speed-gpu.js.map +1 -0
  75. package/dist/gpu/image-kernel-accelerator.d.ts +23 -4
  76. package/dist/gpu/image-kernel-accelerator.js +58 -10
  77. package/dist/gpu/image-kernel-accelerator.js.map +1 -1
  78. package/dist/gpu/image-kernel-execution.d.ts +60 -3
  79. package/dist/gpu/image-kernel-execution.js +2 -2
  80. package/dist/gpu/image-kernel-execution.js.map +1 -1
  81. package/dist/gpu/sensor-stage-gpu.d.ts +11 -0
  82. package/dist/gpu/sensor-stage-gpu.js +42 -13
  83. package/dist/gpu/sensor-stage-gpu.js.map +1 -1
  84. package/dist/gpu/webgpu-runtime.d.ts +4 -2
  85. package/dist/gpu/webgpu-runtime.js +13 -4
  86. package/dist/gpu/webgpu-runtime.js.map +1 -1
  87. package/dist/gpu/webgpu-switch.d.ts +4 -0
  88. package/dist/gpu/webgpu-switch.js +29 -0
  89. package/dist/gpu/webgpu-switch.js.map +1 -0
  90. package/dist/gpu/wgsl-chart-composite-kernel.d.ts +52 -0
  91. package/dist/gpu/wgsl-chart-composite-kernel.js +515 -0
  92. package/dist/gpu/wgsl-chart-composite-kernel.js.map +1 -0
  93. package/dist/gpu/wgsl-chart-kernel.d.ts +11 -9
  94. package/dist/gpu/wgsl-chart-kernel.js +33 -27
  95. package/dist/gpu/wgsl-chart-kernel.js.map +1 -1
  96. package/dist/gpu/wgsl-display-view-quality-kernel.d.ts +95 -0
  97. package/dist/gpu/wgsl-display-view-quality-kernel.js +769 -0
  98. package/dist/gpu/wgsl-display-view-quality-kernel.js.map +1 -0
  99. package/dist/gpu/wgsl-display-view-speed-kernel.d.ts +75 -0
  100. package/dist/gpu/wgsl-display-view-speed-kernel.js +386 -0
  101. package/dist/gpu/wgsl-display-view-speed-kernel.js.map +1 -0
  102. package/dist/gpu/wgsl-sensor-kernel.d.ts +28 -9
  103. package/dist/gpu/wgsl-sensor-kernel.js +94 -50
  104. package/dist/gpu/wgsl-sensor-kernel.js.map +1 -1
  105. package/dist/index.d.ts +6 -3
  106. package/dist/index.js +4 -2
  107. package/dist/index.js.map +1 -1
  108. package/dist/optics/defocus-disc-kernel.d.ts +61 -0
  109. package/dist/optics/defocus-disc-kernel.js +191 -0
  110. package/dist/optics/defocus-disc-kernel.js.map +1 -0
  111. package/dist/optics/irradiance-convolution.d.ts +11 -0
  112. package/dist/optics/irradiance-convolution.js +64 -24
  113. package/dist/optics/irradiance-convolution.js.map +1 -1
  114. package/dist/optics/scene-to-sensor-irradiance.d.ts +13 -0
  115. package/dist/optics/scene-to-sensor-irradiance.js +58 -24
  116. package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
  117. package/dist/optics/sensor-aperture-rays.js +2 -1
  118. package/dist/optics/sensor-aperture-rays.js.map +1 -1
  119. package/dist/optics/sensor-environment-query.js +4 -3
  120. package/dist/optics/sensor-environment-query.js.map +1 -1
  121. package/dist/optics/site-diffraction-kernel.d.ts +16 -0
  122. package/dist/optics/site-diffraction-kernel.js +60 -8
  123. package/dist/optics/site-diffraction-kernel.js.map +1 -1
  124. package/dist/processing/demosaic.js +114 -37
  125. package/dist/processing/demosaic.js.map +1 -1
  126. package/dist/schema/scene-radiance.d.ts +8 -0
  127. package/dist/schema/scene-radiance.js +28 -17
  128. package/dist/schema/scene-radiance.js.map +1 -1
  129. package/dist/sensor/environment-photo-signal.d.ts +21 -0
  130. package/dist/sensor/environment-photo-signal.js +68 -2
  131. package/dist/sensor/environment-photo-signal.js.map +1 -1
  132. package/docs/API_REFERENCE.md +60 -1
  133. package/docs/QUICK_START.md +120 -11
  134. package/docs/USAGE.md +82 -2
  135. package/docs/api/core-version.md +1 -1
  136. package/docs/api/exports.json +157 -2
  137. package/docs/api/facade-chart-material-layers.md +137 -0
  138. package/docs/api/facade-chart-radiance-batch.md +7 -2
  139. package/docs/api/facade-display-view-gpu.md +94 -0
  140. package/docs/api/facade-display-view.md +50 -0
  141. package/docs/api/facade-scene-radiance.md +3 -2
  142. package/docs/api/facade-simulate-capture.md +81 -12
  143. package/docs/api/facade-simulate-display-view.md +39 -2
  144. package/docs/api/gpu-image-kernel-accelerator.md +10 -3
  145. package/docs/api/gpu-image-kernel-execution.md +76 -4
  146. package/docs/api/gpu-webgpu-switch.md +23 -0
  147. package/package.json +3 -1
@@ -0,0 +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 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"]}
@@ -0,0 +1,146 @@
1
+ import type { ChartCompositeProbeRecord, ImageKernelAdapterDescription, ImageKernelExecution, ImageKernelFallbackReason } from "../gpu/image-kernel-execution.js";
2
+ import type { DisplayViewRenderResult, DisplayViewSetup } from "./display-view.js";
3
+ import type { SimulateCaptureFastReport } from "./simulate-capture.js";
4
+ /**
5
+ * 2.11 (#481): whether a prepared display view may render on the GPU. `"off"` (the default) is the CPU reference, today's
6
+ * behaviour byte for byte. `"auto"` renders on WebGPU when a conforming device is available and the request is supported, and
7
+ * otherwise runs the CPU reference and says why. `"require"` fails instead of falling back. In the accelerator's words: `"auto"`
8
+ * is `backend: "webgpu-f32"` with `fallback: "cpu-reference"`, `"require"` is `fallback: "fail"`, `"off"` is `backend: "cpu-reference"`.
9
+ */
10
+ export type DisplayViewGpuMode = "off" | "auto" | "require";
11
+ /** 2.11 (#481): the second argument of `prepareDisplayView`. */
12
+ export interface PrepareDisplayViewOptions {
13
+ /** See {@link DisplayViewGpuMode}. Default `"off"`. */
14
+ gpu?: DisplayViewGpuMode;
15
+ /**
16
+ * Where the device comes from, with `gpu: "auto"` or `"require"`: a WebGPU entry point (a worker's `navigator.gpu`), or an
17
+ * `ImageKernelAccelerator` whose device the view shares (the accelerator keeps ownership; `dispose()` of the prepared view
18
+ * leaves it alone). Without it the engine acquires a device from `globalThis.navigator.gpu` and owns it until `dispose()`.
19
+ * Refused with `gpu: "off"`.
20
+ */
21
+ gpuDevice?: unknown;
22
+ }
23
+ /** The parsed form of {@link PrepareDisplayViewOptions}. @internal */
24
+ export interface ParsedPrepareDisplayViewOptions {
25
+ gpu: DisplayViewGpuMode;
26
+ gpuDevice: unknown;
27
+ }
28
+ /** Internal: validates the second argument of `prepareDisplayView`. */
29
+ export declare function parsePrepareDisplayViewOptions(value: unknown): ParsedPrepareDisplayViewOptions;
30
+ /**
31
+ * 2.11 (#481): why a display view that asked for the GPU (`gpu: "auto"`) ran the CPU reference. The accelerator's acquisition
32
+ * reasons, plus: `unsupported-on-backend` (no GPU display-view renderer exists in this version, or it does not support the
33
+ * request), `conformance-failed` (the device failed the run-time self-check before the view's first GPU render), `device-lost`
34
+ * (the device was lost; the rest of the view runs on the CPU) and `disposed` (the prepared view was disposed).
35
+ */
36
+ export type DisplayViewGpuFallbackReason = ImageKernelFallbackReason | "unsupported-on-backend" | "conformance-failed" | "device-lost" | "disposed";
37
+ /** 2.11 (#481): the run-time conformance self-check of a device, run once before the view's first GPU render. */
38
+ export interface DisplayViewGpuConformance {
39
+ /** The ids of the cases run, in order (the built-in image-kernel cases, then the renderer's own). */
40
+ cases: readonly string[];
41
+ passed: boolean;
42
+ /** The first case that failed, or null. */
43
+ failedCase: string | null;
44
+ /** What the failed case reported, or null. */
45
+ detail: string | null;
46
+ }
47
+ /**
48
+ * 2.11 (#481): where a display view's render ran, in the words of the image-kernel execution record (`ImageKernelExecution`):
49
+ * `backend` names the path that ran (`cpu-reference`, the float64 engine reference, or `webgpu-f32`, a float32 approximation
50
+ * within `errorBound`), `requestedBackend` what `gpu` asked for, and `fallbackReason` why a request for the GPU ran the CPU.
51
+ * `adapter` describes the device's adapter whenever one was involved, also when the view then fell back; `conformance` is
52
+ * the device's self-check once it has run. A CPU render keeps `assurance: "engine-reference"` and `fast: false`.
53
+ */
54
+ export interface DisplayViewExecution extends Omit<ImageKernelExecution, "fallbackReason"> {
55
+ /** The `gpu` option the view was prepared with. */
56
+ gpu: DisplayViewGpuMode;
57
+ fallbackReason: DisplayViewGpuFallbackReason | null;
58
+ adapter: ImageKernelAdapterDescription | null;
59
+ conformance: DisplayViewGpuConformance | null;
60
+ /**
61
+ * 2.11: the composite chart kernel's device probe when this render needed it (composite charts, the 2.3 elements and
62
+ * `material-layers` scenes): the device class and the product path the kernel ran with, or, on a refusal (`fallbackReason`
63
+ * `unsupported-on-backend`), why. Null when the render did not run the probe (the 2.0 presets, `gpu: "off"`).
64
+ */
65
+ compositeProbe: ChartCompositeProbeRecord | null;
66
+ }
67
+ /** 2.11 (#481): `diagnostics.fast` of a display view: the capture's report plus where the render ran. */
68
+ export interface DisplayViewFastReport extends SimulateCaptureFastReport {
69
+ /** Where this render ran (see {@link DisplayViewExecution}). `assurance` above follows it. */
70
+ execution: DisplayViewExecution;
71
+ }
72
+ /** Internal: the execution record of a display view rendered on the CPU reference. `requested` names what `gpu` asked for. */
73
+ export declare function cpuDisplayViewExecution(gpu: DisplayViewGpuMode, fallbackReason: DisplayViewGpuFallbackReason | null, adapter: ImageKernelAdapterDescription | null, conformance: DisplayViewGpuConformance | null, detail?: string, compositeProbe?: ChartCompositeProbeRecord | null): DisplayViewExecution;
74
+ /**
75
+ * Internal (#481): the device a renderer or conformance case runs on. It is the engine's `WebGpuRuntime` object
76
+ * (`src/gpu/webgpu-runtime.ts`: `device`, `guard`, `destroy` and the rest), seen here through its WebGPU-free members only so
77
+ * that no WebGPU type reaches the published declarations (docs/WEBGPU.md); a renderer in the engine casts it to `WebGpuRuntime`.
78
+ */
79
+ export interface DisplayViewGpuRuntimeHandle {
80
+ readonly adapter: ImageKernelAdapterDescription | null;
81
+ readonly maximumStorageBindingBytes: number;
82
+ readonly maximumWorkgroupsPerDimension: number;
83
+ isLost(): boolean;
84
+ }
85
+ /** What a prepared request asks of a GPU renderer (`supports`): the options that shape a render. */
86
+ export interface DisplayViewGpuRequest {
87
+ ahd: boolean;
88
+ diffraction: boolean;
89
+ antiAliasing: boolean;
90
+ /** Pixel-aperture samples per axis (1: centre sampling). */
91
+ boxSamples: number;
92
+ toneCurve: "identity" | "positive-reinhard-per-channel";
93
+ /**
94
+ * #492: true when `lens.defocus` needs the defocus disc (out of focus): the expected signal then carries the disc, or each
95
+ * node's diffraction kernel convolved with it, as site kernels (#492 step 2b), which the engine's renderer gathers in its
96
+ * Quality site pass (step 2c). Absent or false otherwise.
97
+ */
98
+ defocus?: boolean;
99
+ /** The scene's form: an engine chart, a declared `material-layers` scene (#491), or a caller function. */
100
+ scene: "chart" | "material-layers" | "material-function" | "reflectance-function" | "radiance-function";
101
+ }
102
+ /** One render of a region: the CPU renderer's own setup (tables, readout, demosaic, region, callbacks) and the render's signal. */
103
+ export interface DisplayViewGpuPart {
104
+ setup: DisplayViewSetup;
105
+ signal: AbortSignal | undefined;
106
+ }
107
+ /** What a GPU render returns: the CPU renderer's result shape plus the a-priori bound of its values against the reference. */
108
+ export interface DisplayViewGpuRenderOutput extends DisplayViewRenderResult {
109
+ errorBound: NonNullable<ImageKernelExecution["errorBound"]>;
110
+ /** Samples whose float32 classification fell inside its bound (0 when none). */
111
+ diagnosticUncertaintySampleCount?: number;
112
+ /** The composite chart kernel's device probe record, when the render used the composite material module. */
113
+ compositeProbe?: ChartCompositeProbeRecord;
114
+ }
115
+ /** 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. */
116
+ export interface DisplayViewGpuConformanceCase {
117
+ id: string;
118
+ run(runtime: DisplayViewGpuRuntimeHandle, signal: AbortSignal | undefined): Promise<true | string>;
119
+ }
120
+ /**
121
+ * Internal (#481): the contract a GPU display-view renderer fulfils (#478). One instance serves one device, created by the
122
+ * registered factory for each prepared view that acquires or shares a device. `supports` says whether the renderer covers a
123
+ * prepared request (`true`) or why not (a sentence; the view then runs the CPU reference labelled `unsupported-on-backend`).
124
+ * `render` renders one region on the device and must throw `ImageKernelExecutionError` with reason `device-lost` or `aborted`
125
+ * for those two events, as the accelerator's operations do; a render that throws `unsupported-on-backend` (a request the
126
+ * renderer finds it does not cover only when rendering) runs the CPU reference labelled with that reason, or fails with it under
127
+ * `"require"`. `conformanceCases` are run after the built-in image-kernel cases before the device's first render; a failure keeps
128
+ * the whole view on the CPU. `dispose` releases what the renderer holds on the device (#491: uploaded scene records); the session
129
+ * calls it when the prepared view is disposed.
130
+ */
131
+ export interface DisplayViewGpuRenderer {
132
+ readonly id: string;
133
+ supports(request: DisplayViewGpuRequest): true | string;
134
+ render(part: DisplayViewGpuPart): Promise<DisplayViewGpuRenderOutput>;
135
+ readonly conformanceCases?: readonly DisplayViewGpuConformanceCase[];
136
+ dispose?(): void;
137
+ }
138
+ export type DisplayViewGpuRendererFactory = (runtime: DisplayViewGpuRuntimeHandle) => DisplayViewGpuRenderer;
139
+ /**
140
+ * Internal (#481): registers the renderer that `prepareDisplayView` uses for `gpu: "auto" | "require"`, and returns the one
141
+ * registered before (null: none). #478's renderer registers itself here; tests register a fake. With none registered no device
142
+ * is requested and every GPU request falls back (or fails) with `unsupported-on-backend`.
143
+ */
144
+ export declare function setDisplayViewGpuRendererFactory(factory: DisplayViewGpuRendererFactory | null): DisplayViewGpuRendererFactory | null;
145
+ /** Internal: the registered factory. */
146
+ export declare function displayViewGpuRendererFactory(): DisplayViewGpuRendererFactory | null;
@@ -0,0 +1,59 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * #481: how a prepared display view chooses between a WebGPU preview renderer and the CPU reference, and how a render labels
4
+ * which ran. This module holds the option, the label and the renderer contract and imports nothing from the GPU code, so a
5
+ * bundle that never asks for the GPU (`gpu: "off"`, the default) does not contain it; the device handling lives in
6
+ * `display-view-gpu-session.ts`, loaded on demand by `prepareDisplayView` when `gpu` is `"auto"` or `"require"`.
7
+ *
8
+ * The vocabulary is the image-kernel accelerator's (`createImageKernelAccelerator`, docs/WEBGPU.md): `"auto"` is
9
+ * `backend: "webgpu-f32"` with `fallback: "cpu-reference"`, `"require"` is `fallback: "fail"`, `"off"` is
10
+ * `backend: "cpu-reference"`. The render's `diagnostics.fast.execution` names the backend that ran, the fallback reason and the
11
+ * bound in the fields of `ImageKernelExecution`, plus the adapter and the run-time conformance check.
12
+ *
13
+ * No GPU display-view renderer exists yet (#478, #479): until one registers itself through {@link setDisplayViewGpuRendererFactory},
14
+ * `"auto"` runs the CPU reference labelled `unsupported-on-backend` without touching a device, and `"require"` fails with that reason.
15
+ */
16
+ import { InvalidConfigurationError } from "../core/configuration-error.js";
17
+ /** Internal: validates the second argument of `prepareDisplayView`. */
18
+ export function parsePrepareDisplayViewOptions(value) {
19
+ if (value === undefined)
20
+ return { gpu: "off", gpuDevice: undefined };
21
+ if (typeof value !== "object" || value === null || Array.isArray(value))
22
+ throw new InvalidConfigurationError("prepareDisplayView options must be an object { gpu, gpuDevice }.");
23
+ for (const key of Object.keys(value))
24
+ if (key !== "gpu" && key !== "gpuDevice")
25
+ throw new InvalidConfigurationError("Unknown prepareDisplayView options field: " + key + ".");
26
+ const { gpu, gpuDevice } = value;
27
+ const mode = gpu === undefined ? "off" : gpu;
28
+ if (mode !== "off" && mode !== "auto" && mode !== "require")
29
+ throw new InvalidConfigurationError("prepareDisplayView options.gpu must be \"off\", \"auto\" or \"require\".");
30
+ if (gpuDevice !== undefined && (typeof gpuDevice !== "object" || gpuDevice === null))
31
+ throw new InvalidConfigurationError("prepareDisplayView options.gpuDevice must be a WebGPU entry point (navigator.gpu) or an ImageKernelAccelerator.");
32
+ if (gpuDevice !== undefined && mode === "off")
33
+ throw new InvalidConfigurationError("prepareDisplayView options.gpuDevice needs gpu \"auto\" or \"require\".");
34
+ return { gpu: mode, gpuDevice };
35
+ }
36
+ const CPU_LIMITATIONS = Object.freeze(["Float64 engine reference execution; results are the reference by definition"]);
37
+ /** Internal: the execution record of a display view rendered on the CPU reference. `requested` names what `gpu` asked for. */
38
+ export function cpuDisplayViewExecution(gpu, fallbackReason, adapter, conformance, detail, compositeProbe = null) {
39
+ const requestedBackend = gpu === "off" ? "cpu-reference" : "webgpu-f32";
40
+ const limitations = detail === undefined ? CPU_LIMITATIONS : Object.freeze([...CPU_LIMITATIONS, "WebGPU was requested (gpu: \"" + gpu + "\") and the CPU reference ran: " + detail]);
41
+ return Object.freeze({ gpu, backend: "cpu-reference", requestedBackend, fallbackReason, arithmetic: "float64", assurance: "engine-reference", fast: false,
42
+ bitIdenticalToReference: true, errorBound: null, diagnosticsExact: true, diagnosticUncertaintySampleCount: 0, limitations, adapter, conformance, compositeProbe });
43
+ }
44
+ let rendererFactory = null;
45
+ /**
46
+ * Internal (#481): registers the renderer that `prepareDisplayView` uses for `gpu: "auto" | "require"`, and returns the one
47
+ * registered before (null: none). #478's renderer registers itself here; tests register a fake. With none registered no device
48
+ * is requested and every GPU request falls back (or fails) with `unsupported-on-backend`.
49
+ */
50
+ export function setDisplayViewGpuRendererFactory(factory) {
51
+ if (factory !== null && typeof factory !== "function")
52
+ throw new InvalidConfigurationError("setDisplayViewGpuRendererFactory expects a function or null.");
53
+ const previous = rendererFactory;
54
+ rendererFactory = factory;
55
+ return previous;
56
+ }
57
+ /** Internal: the registered factory. */
58
+ export function displayViewGpuRendererFactory() { return rendererFactory; }
59
+ //# sourceMappingURL=display-view-gpu.js.map
@@ -0,0 +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 /** See {@link DisplayViewGpuMode}. Default `\"off\"`. */\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 with `gpu: \"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`. */\nexport function parsePrepareDisplayViewOptions(value: unknown): ParsedPrepareDisplayViewOptions {\n if (value === undefined) return { gpu: \"off\", gpuDevice: undefined };\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 ? \"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 = 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 /** 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"]}
@@ -3,7 +3,34 @@ export declare const DISPLAY_VIEW_JITTER_STREAM_ID: 32;
3
3
  export declare const DISPLAY_VIEW_NOISE_STREAM_ID: 33;
4
4
  export declare const DISPLAY_VIEW_AHD_STREAM_ID: 34;
5
5
  export { createDisplayViewExpectedSignal, type DisplayViewExpectedSignal, type DisplayViewExpectedSignalInput, type DisplayViewQueryOffset, type DisplayViewScene } from "./expected-signal.js";
6
- import type { DisplayViewExpectedSignal } from "./expected-signal.js";
6
+ import type { DisplayViewExpectedSignal, DisplayViewExpectedSignalInput } from "./expected-signal.js";
7
+ import type { ResolvedChartScene } from "./chart-scenes.js";
8
+ import type { ResolvedChartMaterialLayers } from "./chart-material-layers.js";
9
+ /**
10
+ * #478: what a GPU renderer needs beyond the CPU setup, which reads the scene only through `signal`: the expected signal's
11
+ * input (query offsets and points, the materials table, the channel responses) and the resolved chart (null for caller
12
+ * scenes), from which it builds its material lookup. The CPU renderer ignores it.
13
+ */
14
+ export interface DisplayViewGpuSetup {
15
+ signalInput: DisplayViewExpectedSignalInput;
16
+ /** The resolved chart (portable), or null for a caller scene or a declared `material-layers` scene. */
17
+ chart: ResolvedChartScene | null;
18
+ /** #491: the declared `material-layers` scene (its `chart` is the chart under the layers), or null. */
19
+ layers?: ResolvedChartMaterialLayers | null;
20
+ /**
21
+ * #491: a fixed-size chart's placement (`chartSize`): chart-local frame units per frame unit (the metres per frame unit over the
22
+ * chart's half width) and the chart's aspect; outside |cu| ≤ 1, |cv| ≤ aspect the material is the surround, the materials' last entry.
23
+ */
24
+ placement?: {
25
+ chartUnitsPerFrameUnit: number;
26
+ aspect: number;
27
+ } | null;
28
+ /**
29
+ * #492: the defocus disc's radius in sites when the expected signal's kernels carry it (`lens.defocus` out of focus); absent in
30
+ * focus. The GPU Quality site pass then sums each site's taps in blocks (src/gpu/display-view-quality-gpu.ts).
31
+ */
32
+ defocusRadius?: number;
33
+ }
7
34
  /**
8
35
  * Internal (exported for tests). Moments of min(Y, top) for Y ~ N(m, v): mean, variance and the slope d E/d m = P(Y < top). Exact for a normal Y:
9
36
  * E[min(Y,t)] = m − s·(φ(z) − z·(1 − Φ(z))), z = (t − m)/s.
@@ -73,8 +100,16 @@ export interface DisplayViewSetup {
73
100
  drawsPerState: number;
74
101
  thresholdVariance: number;
75
102
  };
103
+ /**
104
+ * #447: a collect pass. The render adds to this set the grid key of every state its corrected samples interpolate between
105
+ * (the corners `gridCorrection` would compute or read), computes and reads no state and leaves the cache untouched; its
106
+ * corrections are zero, so its image is not a display view and is discarded by the caller.
107
+ */
108
+ ahdCollect?: Set<number>;
76
109
  yieldControl(): Promise<void>;
77
110
  checkAbort(): void;
111
+ /** #478: the inputs a GPU renderer builds its scene lookup from (see {@link DisplayViewGpuSetup}); not read by `renderDisplayView`. */
112
+ gpu?: DisplayViewGpuSetup;
78
113
  }
79
114
  export interface DisplayViewRenderResult {
80
115
  samples: Uint8Array | Uint16Array;
@@ -109,6 +144,11 @@ export interface DisplayViewKernelTap {
109
144
  * by homogeneity, which is the only non-linear step. Returns [horizontal, vertical], each [red, green, blue] kernels.
110
145
  */
111
146
  export declare function ahdCandidateKernels(phaseX: number, phaseY: number): DisplayViewKernelTap[][][];
147
+ /** 1-D overlaps of real output columns with one display column: first column index and the overlaps. */
148
+ export declare function overlaps(start: number, end: number, limit: number): {
149
+ first: number;
150
+ w: Float64Array;
151
+ };
112
152
  /**
113
153
  * Internal (exported for tests). Footprint sums along one axis, for the closed-form B_c (docs/DISPLAY_VIEW.md, "Demosaic correlation"). Native
114
154
  * coordinate parity decides the CFA: red columns/rows are even, blue odd. With w(k) the overlap of real column k:
@@ -130,9 +170,84 @@ export interface AxisSums {
130
170
  export declare function axisSums(start: number, end: number, limit: number, margin: number): AxisSums;
131
171
  /** Internal (exported for tests). B for red, green and blue (Σ β² over the channel's sites, β normalized to unit sum) and Σ (w/A)². */
132
172
  export declare function footprintWeights(x: AxisSums, y: AxisSums, area: number, out: Float64Array): void;
173
+ /** Grid of flat-neighbourhood states for the AHD correction: steps per octave of the normalized channel mean, octaves below white (exported for the GPU display view, #479). */
174
+ export declare const AHD_KEY_STEPS = 8, AHD_KEY_OCTAVES = 12;
175
+ /** Lowest grid level, 2^-AHD_KEY_OCTAVES of white (exact). */
176
+ export declare const AHD_KEY_FLOOR: number;
177
+ /** Grid levels per channel (indices 0 to AHD_KEY_OCTAVES·AHD_KEY_STEPS). */
178
+ export declare const AHD_KEY_LEVELS: number;
179
+ /**
180
+ * Internal (exported for tests, #442): the window offset of each slot, slot (dy + reach)·(2·reach + 1) + dx + reach, as
181
+ * two integer tables: dx[slot] = (slot mod side) − reach and dy[slot] = ⌊slot / side⌋ − reach. The render loop reads them
182
+ * instead of taking a modulo and a division per site read; they are the same integers.
183
+ */
184
+ export declare function displayViewSlotOffsets(reach: number): {
185
+ dx: Int32Array;
186
+ dy: Int32Array;
187
+ };
188
+ /** The per-phase candidate tables of a render, flat (#442): index phase·2 + candidate, and ·3 + channel for the slots and weights. */
189
+ export interface DisplayViewCandidateTables {
190
+ /** Candidates per phase: 1 (bilinear) or 2 (AHD), the same for every phase. */
191
+ count: number;
192
+ denseAt: Float64Array[];
193
+ listAt: Int32Array[];
194
+ slotsAt: Int32Array[];
195
+ weightsAt: Float64Array[];
196
+ }
197
+ /**
198
+ * Internal (exported for tests, #442): the nested per-phase tables [phase][candidate] (and [channel]) as flat arrays holding
199
+ * the same typed arrays. Plain arrays of typed arrays with one element kind keep the render loop's keyed loads on one hidden
200
+ * class each, where the nested arrays (arrays of arrays of typed arrays) made V8 deoptimize the render loop. Every phase must
201
+ * have the same number of candidates, 1 or 2 (the record layout and the choice variance assume it), each with 3 channels.
202
+ */
203
+ export declare function flatDisplayViewCandidateTables(slots: readonly (readonly (readonly Int32Array[])[])[], weights: readonly (readonly (readonly Float64Array[])[])[], dense: readonly (readonly Float64Array[])[], list: readonly (readonly Int32Array[])[]): DisplayViewCandidateTables;
133
204
  /** Internal (exported for tests): the correction states kept across calls, and clearing them. */
134
205
  export declare function displayViewCorrectionStateCount(): number;
135
206
  export declare function clearDisplayViewCorrectionStates(): void;
207
+ /**
208
+ * 2.10 (#447): the AHD low-signal correction states of one setup, as a realm sends them to another. `key` is the setup's
209
+ * correction key (`PreparedDisplayView.correctionKey()`), `gridKeys[i]` a state's grid key and `values[3·i …]` its three
210
+ * values (28 bytes per state). Both arrays are transferable.
211
+ */
212
+ export interface DisplayViewCorrectionStateSet {
213
+ key: string;
214
+ gridKeys: Int32Array;
215
+ values: Float64Array;
216
+ }
217
+ /** 2.10 (#447): the grid keys of the states a region needs (`PreparedDisplayView.collectCorrectionStates`), ascending. */
218
+ export interface DisplayViewCorrectionStateKeys {
219
+ key: string;
220
+ gridKeys: Int32Array;
221
+ }
222
+ /** The inputs of one setup's correction states: the inputs of its correction key. */
223
+ export type DisplayViewCorrectionSetup = Pick<DisplayViewSetup, "seed" | "readout" | "gains" | "clipLevel" | "matrix" | "toneCurve"> & {
224
+ ahdCorrection: NonNullable<DisplayViewSetup["ahdCorrection"]>;
225
+ };
226
+ /** Internal (#447): the correction key of a setup, or null without the AHD correction (the key `renderDisplayView` looks its states up with). */
227
+ export declare function displayViewCorrectionKey(setup: Pick<DisplayViewSetup, "seed" | "readout" | "gains" | "clipLevel" | "matrix" | "toneCurve" | "ahdCorrection">): string | null;
228
+ /**
229
+ * 2.10 (#447): the AHD low-signal correction states this JavaScript realm holds (a Web Worker, a page), one entry per cached
230
+ * setup, least recently used first, each state's grid key and three values copied out. Another realm adds them with
231
+ * {@link bindDisplayViewCorrectionStates}; a render there then reads them instead of computing them, with the same bytes.
232
+ */
233
+ export declare function serializeDisplayViewCorrectionStates(): DisplayViewCorrectionStateSet[];
234
+ /**
235
+ * 2.10 (#447): adds states another realm computed (an export, or `computeCorrectionStates` results) to this realm's cache and
236
+ * returns the number of states added. For each entry, the grid keys its setup does not hold yet are appended; known ones are
237
+ * left as they are (a state's values follow from its key, so they are equal). Every entry is checked before the cache is
238
+ * touched: `key` a non-empty string, `gridKeys` an Int32Array of grid keys, `values` a Float64Array of 3 × `gridKeys.length`
239
+ * finite numbers; otherwise it fails with an InvalidConfigurationError and the cache is unchanged. The cache's bounds apply as
240
+ * in a render: an unknown key creates a setup and can evict the least recently used of the four kept, and a setup that
241
+ * reaches 65 536 states is cleared before the next one is added. Import only keys a prepared view reported
242
+ * (`correctionKey()`), so states a render here will read.
243
+ */
244
+ export declare function bindDisplayViewCorrectionStates(entries: readonly DisplayViewCorrectionStateSet[]): number;
245
+ /**
246
+ * Internal (#447, `PreparedDisplayView.computeCorrectionStates`): computes the states of the given grid keys for a setup (each
247
+ * as a render computes it, read from the cache where it is held) and stores them in this realm's cache; returns each key's
248
+ * three values in the order given. Yields to the host and checks for abort between states, as a render does.
249
+ */
250
+ export declare function computeDisplayViewCorrectionStates(setup: DisplayViewCorrectionSetup & Pick<DisplayViewSetup, "yieldControl" | "checkAbort">, gridKeys: Int32Array): Promise<DisplayViewCorrectionStateSet>;
136
251
  /**
137
252
  * Most real pixels a footprint may hold for the exact area mean (#393). Measured on 8-row strips of a 24 MP view (Siemens star
138
253
  * and dead leaves, one thread): the exact path matched the stratified estimator's time within run-to-run spread up to 25 real
@@ -142,3 +257,10 @@ export declare function clearDisplayViewCorrectionStates(): void;
142
257
  export declare const EXACT_AREA_MEAN_MAX_PIXELS = 25;
143
258
  /** Renders the display view (docs/DISPLAY_VIEW.md). */
144
259
  export declare function renderDisplayView(setup: DisplayViewSetup): Promise<DisplayViewRenderResult>;
260
+ /**
261
+ * The centre c of a normal of variance v whose clip to [0, 1] has mean `target` (bisection; c = target when the noise does
262
+ * not reach a bound, or when the target lies outside (0, 1)).
263
+ */
264
+ export declare function clipCentre(target: number, v: number): number;
265
+ /** Variance in linear light of rounding an sRGB-encoded value to steps of `step`: (dEOTF/de)²·step²/12 at the encoded mean. */
266
+ export declare function quantizationVariance(linear: number, step: number): number;