Skip to content

Commit 36c9c3b

Browse files
authored
slightly speedup XYB by doing a TODO (#801)
1 parent e7436b8 commit 36c9c3b

1 file changed

Lines changed: 31 additions & 34 deletions

File tree

jxl/src/render/stages/xyb.rs

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -142,17 +142,37 @@ impl OutputColorInfo {
142142
}
143143
}
144144

145+
/// Precomputed per-frame constants for `xyb_process`.
146+
struct XybParams {
147+
mat: [f32; 9],
148+
bias_cbrt: [f32; 3],
149+
scaled_bias: [f32; 3],
150+
intensity_scale: f32,
151+
}
152+
153+
impl XybParams {
154+
fn new(opsin: &OpsinInverseMatrix, intensity_target: f32) -> Self {
155+
let intensity_scale = 255.0 / intensity_target;
156+
Self {
157+
mat: opsin.inverse_matrix,
158+
bias_cbrt: opsin.opsin_biases.map(|x| x.cbrt()),
159+
scaled_bias: opsin.opsin_biases.map(|x| x * intensity_scale),
160+
intensity_scale,
161+
}
162+
}
163+
}
164+
145165
/// Convert XYB to linear RGB with appropriate primaries, where 1.0 corresponds to `intensity_target` nits.
146166
pub struct XybStage {
147167
first_channel: usize,
148-
output_color_info: OutputColorInfo,
168+
params: XybParams,
149169
}
150170

151171
impl XybStage {
152172
pub fn new(first_channel: usize, output_color_info: OutputColorInfo) -> Self {
153173
Self {
154174
first_channel,
155-
output_color_info,
175+
params: XybParams::new(&output_color_info.opsin, output_color_info.intensity_target),
156176
}
157177
}
158178
}
@@ -174,24 +194,16 @@ simd_function!(
174194
xyb_process_dispatch,
175195
d: D,
176196
fn xyb_process(
177-
opsin: &OpsinInverseMatrix,
178-
intensity_target: f32,
197+
params: &XybParams,
179198
xsize: usize,
180199
row_x: &mut [f32],
181200
row_y: &mut [f32],
182201
row_b: &mut [f32],
183202
) {
184-
let OpsinInverseMatrix {
185-
inverse_matrix: mat,
186-
opsin_biases: bias,
187-
..
188-
} = opsin;
189-
// TODO(veluca): consider computing the cbrt in advance.
190-
let bias_cbrt = bias.map(|x| D::F32Vec::splat(d, x.cbrt()));
191-
let intensity_scale = 255.0 / intensity_target;
192-
let scaled_bias = bias.map(|x| D::F32Vec::splat(d, x * intensity_scale));
193-
let mat = mat.map(|x| D::F32Vec::splat(d, x));
194-
let intensity_scale = D::F32Vec::splat(d, intensity_scale);
203+
let mat = params.mat.map(|x| D::F32Vec::splat(d, x));
204+
let bias_cbrt = params.bias_cbrt.map(|x| D::F32Vec::splat(d, x));
205+
let scaled_bias = params.scaled_bias.map(|x| D::F32Vec::splat(d, x));
206+
let intensity_scale = D::F32Vec::splat(d, params.intensity_scale);
195207

196208
for idx in (0..xsize).step_by(D::F32Vec::LEN) {
197209
let x = D::F32Vec::load(d, &row_x[idx..]);
@@ -246,14 +258,7 @@ impl RenderPipelineInPlaceStage for XybStage {
246258
);
247259
};
248260

249-
xyb_process_dispatch(
250-
&self.output_color_info.opsin,
251-
self.output_color_info.intensity_target,
252-
xsize,
253-
row_x,
254-
row_y,
255-
row_b,
256-
);
261+
xyb_process_dispatch(&self.params, xsize, row_x, row_y, row_b);
257262
}
258263
}
259264

@@ -324,20 +329,12 @@ mod test {
324329
let mut scalar_y = row_y.clone();
325330
let mut scalar_b = row_b.clone();
326331

327-
xyb_process(
328-
d,
329-
&opsin,
330-
intensity_target,
331-
xsize,
332-
&mut row_x,
333-
&mut row_y,
334-
&mut row_b,
335-
);
332+
let params = XybParams::new(&opsin, intensity_target);
336333

334+
xyb_process(d, &params, xsize, &mut row_x, &mut row_y, &mut row_b);
337335
xyb_process(
338336
ScalarDescriptor::new().unwrap(),
339-
&opsin,
340-
intensity_target,
337+
&params,
341338
xsize,
342339
&mut scalar_x,
343340
&mut scalar_y,

0 commit comments

Comments
 (0)