Renderer: colour caches key colours with Color::key

The freeform and dithered gradient grids and the separated inks each built the same exact colour key by hand; they now take the one Color::key gives.
This commit is contained in:
Jürg Lehni
2026-10-24 04:49:07 +07:00
committed by bflatastic
parent 5020dc0585
commit 181aeef44c
3 changed files with 8 additions and 18 deletions
+1 -2
View File
@@ -20,7 +20,6 @@ use vectorcraft_geom::{Affine, Rect};
use vello_cpu::peniko::{Extend, ImageQuality, ImageSampler};
use vello_cpu::{Pixmap, RenderContext};
use crate::freeform::hash_color;
use crate::ink::Ink;
use crate::lru::{self, FrameCache};
@@ -60,7 +59,7 @@ fn key(g: &GradientPaint, b: Rect, cols: u16, rows: u16, win: &[Range<u16>; 2],
(gr.kind as u8, gr.dither, gr.method as u8).hash(&mut h);
for s in &gr.stops {
(s.offset.to_bits(), s.opacity.to_bits(), s.midpoint.to_bits()).hash(&mut h);
hash_color(&s.color, &mut h);
s.color.key().hash(&mut h);
}
let geom = g.resolve(b);
(geom.start.x.to_bits(), geom.start.y.to_bits(), geom.end.x.to_bits(), geom.end.y.to_bits(), geom.aspect.to_bits()).hash(&mut h);
+2 -11
View File
@@ -11,7 +11,7 @@ use std::hash::{Hash, Hasher};
use std::sync::Arc;
use vectorcraft_color::freeform::{grid_size, painted_box, spread_scale};
use vectorcraft_color::{Color, Freeform, GradientPaint};
use vectorcraft_color::{Freeform, GradientPaint};
use vectorcraft_geom::{Affine, Rect};
use vello_cpu::peniko::{Extend, ImageQuality, ImageSampler};
use vello_cpu::{Pixmap, RenderContext};
@@ -24,22 +24,13 @@ thread_local! {
static GRIDS: RefCell<FrameCache<u64, Arc<Pixmap>>> = RefCell::new(FrameCache::new(lru::FREEFORM_BUDGET, usize::MAX));
}
pub(crate) fn hash_color(c: &Color, h: &mut impl Hasher) {
match *c {
Color::Rgb { r, g, b } => (0u8, r.to_bits(), g.to_bits(), b.to_bits()).hash(h),
Color::Cmyk { c, m, y, k } => (1u8, c.to_bits(), m.to_bits(), y.to_bits(), k.to_bits()).hash(h),
Color::Gray { k } => (2u8, k.to_bits()).hash(h),
Color::Lab { l, a, b } => (3u8, l.to_bits(), a.to_bits(), b.to_bits()).hash(h),
}
}
/// Cache key of the grid of `f` on box `b` at `cols` × `rows` painted with `ink` (and the active
/// colour settings, which turn colours into display RGB or inks).
fn key(f: &Freeform, b: Rect, cols: u16, rows: u16, ink: Ink) -> u64 {
let mut h = std::collections::hash_map::DefaultHasher::new();
for p in &f.points {
(p.at.x.to_bits(), p.at.y.to_bits(), p.opacity.to_bits(), p.spread.to_bits()).hash(&mut h);
hash_color(&p.color, &mut h);
p.color.key().hash(&mut h);
}
f.lines.hash(&mut h);
(b.x0.to_bits(), b.y0.to_bits(), b.x1.to_bits(), b.y1.to_bits(), cols, rows).hash(&mut h);
+5 -5
View File
@@ -121,12 +121,12 @@ impl Renderer {
/// The inks of `c` in the working CMYK space: CMYK as it is, grey as black ink, RGB and Lab
/// separated with the colour settings' intent (cached: separating searches the profile).
fn inks(c: &Color) -> [f32; 4] {
let key = match *c {
match *c {
Color::Cmyk { c, m, y, k } => return [c, m, y, k],
Color::Gray { k } => return [0.0, 0.0, 0.0, k],
Color::Rgb { r, g, b } => [0, r.to_bits(), g.to_bits(), b.to_bits()],
Color::Lab { l, a, b } => [1, l.to_bits(), a.to_bits(), b.to_bits()],
};
Color::Rgb { .. } | Color::Lab { .. } => {}
}
let key = c.key();
let cms = cms::active();
SEPARATED.with(|s| {
let (owner, seen) = &mut *s.borrow_mut();
@@ -141,7 +141,7 @@ fn inks(c: &Color) -> [f32; 4] {
}
/// Separated colours, for the colour settings they were separated with.
type Separated = (Option<Arc<Cms>>, HashMap<[u32; 4], [f32; 4]>);
type Separated = (Option<Arc<Cms>>, HashMap<[u32; 5], [f32; 4]>);
thread_local! {
static SEPARATED: RefCell<Separated> = RefCell::default();