@photivra/engine 2.10.0 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +156 -1
- package/CITATION.cff +1 -1
- package/NODE_SUPPORT.md +19 -3
- package/README.md +6 -6
- package/SECURITY.md +1 -1
- package/dist/core/portable-math.d.ts +6 -0
- package/dist/core/portable-math.js +39 -0
- package/dist/core/portable-math.js.map +1 -1
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/dist/core/version.js.map +1 -1
- package/dist/facade/chart-material-layers.d.ts +115 -0
- package/dist/facade/chart-material-layers.js +224 -0
- package/dist/facade/chart-material-layers.js.map +1 -0
- package/dist/facade/chart-radiance-batch.d.ts +8 -2
- package/dist/facade/chart-radiance-batch.js +11 -4
- package/dist/facade/chart-radiance-batch.js.map +1 -1
- package/dist/facade/chart-scenes.d.ts +134 -0
- package/dist/facade/chart-scenes.js +32 -22
- package/dist/facade/chart-scenes.js.map +1 -1
- package/dist/facade/diffraction-provider.d.ts +8 -2
- package/dist/facade/diffraction-provider.js +71 -2
- package/dist/facade/diffraction-provider.js.map +1 -1
- package/dist/facade/display-view-gpu-session.d.ts +18 -0
- package/dist/facade/display-view-gpu-session.js +280 -0
- package/dist/facade/display-view-gpu-session.js.map +1 -0
- package/dist/facade/display-view-gpu.d.ts +146 -0
- package/dist/facade/display-view-gpu.js +59 -0
- package/dist/facade/display-view-gpu.js.map +1 -0
- package/dist/facade/display-view.d.ts +48 -1
- package/dist/facade/display-view.js +7 -7
- package/dist/facade/display-view.js.map +1 -1
- package/dist/facade/expected-signal-setup.d.ts +5 -0
- package/dist/facade/expected-signal-setup.js +16 -0
- package/dist/facade/expected-signal-setup.js.map +1 -1
- package/dist/facade/expected-signal.d.ts +48 -3
- package/dist/facade/expected-signal.js +8 -0
- package/dist/facade/expected-signal.js.map +1 -1
- package/dist/facade/scene-radiance.d.ts +4 -2
- package/dist/facade/scene-radiance.js +7 -4
- package/dist/facade/scene-radiance.js.map +1 -1
- package/dist/facade/simulate-capture.d.ts +108 -8
- package/dist/facade/simulate-capture.js +226 -33
- package/dist/facade/simulate-capture.js.map +1 -1
- package/dist/facade/simulate-display-view.d.ts +31 -3
- package/dist/facade/simulate-display-view.js +73 -13
- package/dist/facade/simulate-display-view.js.map +1 -1
- package/dist/gpu/chart-composite-gpu.d.ts +119 -0
- package/dist/gpu/chart-composite-gpu.js +572 -0
- package/dist/gpu/chart-composite-gpu.js.map +1 -0
- package/dist/gpu/chart-radiance-gpu.d.ts +6 -6
- package/dist/gpu/chart-radiance-gpu.js +9 -11
- package/dist/gpu/chart-radiance-gpu.js.map +1 -1
- package/dist/gpu/display-view-chart-material-module.d.ts +10 -0
- package/dist/gpu/display-view-chart-material-module.js +58 -0
- package/dist/gpu/display-view-chart-material-module.js.map +1 -0
- package/dist/gpu/display-view-composite-material-module.d.ts +68 -0
- package/dist/gpu/display-view-composite-material-module.js +248 -0
- package/dist/gpu/display-view-composite-material-module.js.map +1 -0
- package/dist/gpu/display-view-quality-gpu.d.ts +185 -0
- package/dist/gpu/display-view-quality-gpu.js +1000 -0
- package/dist/gpu/display-view-quality-gpu.js.map +1 -0
- package/dist/gpu/display-view-speed-gpu.d.ts +156 -0
- package/dist/gpu/display-view-speed-gpu.js +524 -0
- package/dist/gpu/display-view-speed-gpu.js.map +1 -0
- package/dist/gpu/image-kernel-accelerator.d.ts +23 -4
- package/dist/gpu/image-kernel-accelerator.js +58 -10
- package/dist/gpu/image-kernel-accelerator.js.map +1 -1
- package/dist/gpu/image-kernel-execution.d.ts +55 -3
- package/dist/gpu/image-kernel-execution.js.map +1 -1
- package/dist/gpu/sensor-stage-gpu.d.ts +11 -0
- package/dist/gpu/sensor-stage-gpu.js +42 -13
- package/dist/gpu/sensor-stage-gpu.js.map +1 -1
- package/dist/gpu/webgpu-runtime.d.ts +4 -2
- package/dist/gpu/webgpu-runtime.js +13 -4
- package/dist/gpu/webgpu-runtime.js.map +1 -1
- package/dist/gpu/webgpu-switch.d.ts +4 -0
- package/dist/gpu/webgpu-switch.js +29 -0
- package/dist/gpu/webgpu-switch.js.map +1 -0
- package/dist/gpu/wgsl-chart-composite-kernel.d.ts +52 -0
- package/dist/gpu/wgsl-chart-composite-kernel.js +515 -0
- package/dist/gpu/wgsl-chart-composite-kernel.js.map +1 -0
- package/dist/gpu/wgsl-chart-kernel.d.ts +11 -9
- package/dist/gpu/wgsl-chart-kernel.js +33 -27
- package/dist/gpu/wgsl-chart-kernel.js.map +1 -1
- package/dist/gpu/wgsl-display-view-quality-kernel.d.ts +95 -0
- package/dist/gpu/wgsl-display-view-quality-kernel.js +769 -0
- package/dist/gpu/wgsl-display-view-quality-kernel.js.map +1 -0
- package/dist/gpu/wgsl-display-view-speed-kernel.d.ts +75 -0
- package/dist/gpu/wgsl-display-view-speed-kernel.js +386 -0
- package/dist/gpu/wgsl-display-view-speed-kernel.js.map +1 -0
- package/dist/gpu/wgsl-sensor-kernel.d.ts +28 -9
- package/dist/gpu/wgsl-sensor-kernel.js +94 -50
- package/dist/gpu/wgsl-sensor-kernel.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/optics/defocus-disc-kernel.d.ts +61 -0
- package/dist/optics/defocus-disc-kernel.js +191 -0
- package/dist/optics/defocus-disc-kernel.js.map +1 -0
- package/docs/API_REFERENCE.md +47 -1
- package/docs/QUICK_START.md +150 -5
- package/docs/USAGE.md +81 -3
- package/docs/api/core-version.md +1 -1
- package/docs/api/exports.json +127 -2
- package/docs/api/facade-chart-material-layers.md +137 -0
- package/docs/api/facade-chart-radiance-batch.md +7 -2
- package/docs/api/facade-display-view-gpu.md +94 -0
- package/docs/api/facade-scene-radiance.md +3 -2
- package/docs/api/facade-simulate-capture.md +95 -11
- package/docs/api/facade-simulate-display-view.md +17 -2
- package/docs/api/gpu-image-kernel-accelerator.md +10 -3
- package/docs/api/gpu-image-kernel-execution.md +71 -4
- package/docs/api/gpu-webgpu-switch.md +23 -0
- package/package.json +3 -1
|
@@ -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.
|
|
@@ -81,6 +108,8 @@ export interface DisplayViewSetup {
|
|
|
81
108
|
ahdCollect?: Set<number>;
|
|
82
109
|
yieldControl(): Promise<void>;
|
|
83
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;
|
|
84
113
|
}
|
|
85
114
|
export interface DisplayViewRenderResult {
|
|
86
115
|
samples: Uint8Array | Uint16Array;
|
|
@@ -115,6 +144,11 @@ export interface DisplayViewKernelTap {
|
|
|
115
144
|
* by homogeneity, which is the only non-linear step. Returns [horizontal, vertical], each [red, green, blue] kernels.
|
|
116
145
|
*/
|
|
117
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
|
+
};
|
|
118
152
|
/**
|
|
119
153
|
* Internal (exported for tests). Footprint sums along one axis, for the closed-form B_c (docs/DISPLAY_VIEW.md, "Demosaic correlation"). Native
|
|
120
154
|
* coordinate parity decides the CFA: red columns/rows are even, blue odd. With w(k) the overlap of real column k:
|
|
@@ -136,6 +170,12 @@ export interface AxisSums {
|
|
|
136
170
|
export declare function axisSums(start: number, end: number, limit: number, margin: number): AxisSums;
|
|
137
171
|
/** Internal (exported for tests). B for red, green and blue (Σ β² over the channel's sites, β normalized to unit sum) and Σ (w/A)². */
|
|
138
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;
|
|
139
179
|
/**
|
|
140
180
|
* Internal (exported for tests, #442): the window offset of each slot, slot (dy + reach)·(2·reach + 1) + dx + reach, as
|
|
141
181
|
* two integer tables: dx[slot] = (slot mod side) − reach and dy[slot] = ⌊slot / side⌋ − reach. The render loop reads them
|
|
@@ -217,3 +257,10 @@ export declare function computeDisplayViewCorrectionStates(setup: DisplayViewCor
|
|
|
217
257
|
export declare const EXACT_AREA_MEAN_MAX_PIXELS = 25;
|
|
218
258
|
/** Renders the display view (docs/DISPLAY_VIEW.md). */
|
|
219
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;
|
|
@@ -220,7 +220,7 @@ export function ahdCandidateKernels(phaseX, phaseY) {
|
|
|
220
220
|
});
|
|
221
221
|
}
|
|
222
222
|
/** 1-D overlaps of real output columns with one display column: first column index and the overlaps. */
|
|
223
|
-
function overlaps(start, end, limit) {
|
|
223
|
+
export function overlaps(start, end, limit) {
|
|
224
224
|
const first = Math.floor(start), last = Math.min(limit - 1, Math.ceil(end) - 1), w = new Float64Array(last - first + 1);
|
|
225
225
|
for (let k = first; k <= last; k++)
|
|
226
226
|
w[k - first] = Math.min(end, k + 1) - Math.max(start, k);
|
|
@@ -260,8 +260,8 @@ export function footprintWeights(x, y, area, out) {
|
|
|
260
260
|
}
|
|
261
261
|
/** AHD's dependence reach in sites (directional green ±2, colour differences ±1, homogeneity 4-neighbours and 3 × 3 sum). */
|
|
262
262
|
const AHD_REACH = 5, AHD_SIDE = 2 * AHD_REACH + 1;
|
|
263
|
-
/** Grid of flat-neighbourhood states for the AHD correction: steps per octave of the normalized channel mean, octaves below white. */
|
|
264
|
-
const AHD_KEY_STEPS = 8, AHD_KEY_OCTAVES = 12;
|
|
263
|
+
/** 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). */
|
|
264
|
+
export const AHD_KEY_STEPS = 8, AHD_KEY_OCTAVES = 12;
|
|
265
265
|
/** CFA role (0 red, 1 green, 2 blue) of each patch site (dy + 5)·11 + dx + 5, per phase (phaseY·2 + phaseX) of the centre. */
|
|
266
266
|
const AHD_ROLES = [0, 1, 2, 3].map((phase) => {
|
|
267
267
|
const roles = new Uint8Array(AHD_SIDE * AHD_SIDE), px = phase & 1, py = phase >> 1;
|
|
@@ -287,9 +287,9 @@ const LAB_EPSILON = 216 / 24389, LAB_KAPPA = 24389 / 27;
|
|
|
287
287
|
/** A 32-bit hash of a correction key (MurmurHash3 finalizer of the three quantized means). */
|
|
288
288
|
function fmixKey(a, b, c) { return fmix32((Math.imul(a + 1, 0x9e3779b1) ^ Math.imul(b + 1, 0x85ebca77) ^ Math.imul(c + 1, 0xc2b2ae3d)) >>> 0); }
|
|
289
289
|
/** Lowest grid level, 2^-AHD_KEY_OCTAVES of white (exact). */
|
|
290
|
-
const AHD_KEY_FLOOR = 1 / 4096;
|
|
290
|
+
export const AHD_KEY_FLOOR = 1 / 4096;
|
|
291
291
|
/** Grid levels per channel (indices 0 to AHD_KEY_OCTAVES·AHD_KEY_STEPS). */
|
|
292
|
-
const AHD_KEY_LEVELS = AHD_KEY_OCTAVES * AHD_KEY_STEPS + 1;
|
|
292
|
+
export const AHD_KEY_LEVELS = AHD_KEY_OCTAVES * AHD_KEY_STEPS + 1;
|
|
293
293
|
/** Correction states kept per setup, and setups kept (least recently used first out); about 50 bytes per state. */
|
|
294
294
|
const AHD_STATE_LIMIT = 1 << 16, AHD_SETUP_LIMIT = 4;
|
|
295
295
|
const ahdStateCache = new Map();
|
|
@@ -1364,7 +1364,7 @@ export async function renderDisplayView(setup) {
|
|
|
1364
1364
|
* The centre c of a normal of variance v whose clip to [0, 1] has mean `target` (bisection; c = target when the noise does
|
|
1365
1365
|
* not reach a bound, or when the target lies outside (0, 1)).
|
|
1366
1366
|
*/
|
|
1367
|
-
function clipCentre(target, v) {
|
|
1367
|
+
export function clipCentre(target, v) {
|
|
1368
1368
|
if (!(v > 0) || !(target > 0 && target < 1))
|
|
1369
1369
|
return target;
|
|
1370
1370
|
const s = Math.sqrt(v);
|
|
@@ -1383,7 +1383,7 @@ function clipCentre(target, v) {
|
|
|
1383
1383
|
return (lo + hi) / 2;
|
|
1384
1384
|
}
|
|
1385
1385
|
/** Variance in linear light of rounding an sRGB-encoded value to steps of `step`: (dEOTF/de)²·step²/12 at the encoded mean. */
|
|
1386
|
-
function quantizationVariance(linear, step) {
|
|
1386
|
+
export function quantizationVariance(linear, step) {
|
|
1387
1387
|
const e = encodeSrgbComponentPortable(linear < 0 ? 0 : linear > 1 ? 1 : linear), slope = e <= 0.04045 ? 1 / 12.92 : 2.4 / 1.055 * portablePow((e + 0.055) / 1.055, 1.4);
|
|
1388
1388
|
return slope * slope * step * step / 12;
|
|
1389
1389
|
}
|