mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-30 18:38:13 +08:00
Count assign colors lanes without legacy conversion and cache the offsets
This commit is contained in:
@@ -770,6 +770,20 @@ const _: () = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// The graphic with every `Group` converted to its legacy form.
|
/// The graphic with every `Group` converted to its legacy form.
|
||||||
|
/// The count [`map_groups_to_legacy`] would expose through [`Graphic::as_vector`],
|
||||||
|
/// read from the run's lanes instead of materializing the legacy list. Mirrors
|
||||||
|
/// [`group_to_legacy_graphic`]'s typed-run path, where `Vector` is tried first.
|
||||||
|
pub fn direct_vector_len(graphic: &Graphic) -> usize {
|
||||||
|
match graphic {
|
||||||
|
Graphic::Vector(list) => list.len(),
|
||||||
|
Graphic::Group(group) => match (&group.row, &group.content) {
|
||||||
|
(None, core_types::record::GroupContent::Run(item)) => item.typed_lanes::<Vector>().map_or(0, |lanes| lanes.len()),
|
||||||
|
_ => 0,
|
||||||
|
},
|
||||||
|
_ => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn map_groups_to_legacy(graphic: &Graphic) -> Graphic {
|
pub fn map_groups_to_legacy(graphic: &Graphic) -> Graphic {
|
||||||
match graphic {
|
match graphic {
|
||||||
Graphic::Group(group) => group_to_legacy_graphic(group),
|
Graphic::Group(group) => group_to_legacy_graphic(group),
|
||||||
|
|||||||
@@ -163,8 +163,9 @@ fn assign_colors_extent(
|
|||||||
/// under the assign colors identifier.
|
/// under the assign colors identifier.
|
||||||
#[node_macro::node(category(""), extent(assign_colors_graphic_extent))]
|
#[node_macro::node(category(""), extent(assign_colors_graphic_extent))]
|
||||||
fn assign_colors_graphic<'e>(
|
fn assign_colors_graphic<'e>(
|
||||||
ctx: impl Ctx + ExtractArena<'e> + ExtractIndex + InjectIndex + Copy,
|
ctx: impl Ctx + CacheHash + ExtractArena<'e> + ExtractIndex + InjectIndex + Copy,
|
||||||
content: IList<Graphic>,
|
content: IList<Graphic>,
|
||||||
|
#[data] lane_offsets: std::sync::Arc<std::sync::Mutex<Option<LaneOffsets>>>,
|
||||||
#[default(true)] fill: bool,
|
#[default(true)] fill: bool,
|
||||||
stroke: bool,
|
stroke: bool,
|
||||||
gradient: IList<GradientStops>,
|
gradient: IList<GradientStops>,
|
||||||
@@ -195,9 +196,27 @@ fn assign_colors_graphic<'e>(
|
|||||||
|
|
||||||
// The interiors the pre-flip node reached: only a lane's DIRECT vector
|
// The interiors the pre-flip node reached: only a lane's DIRECT vector
|
||||||
// list, so wrapped groups keep their own styling and consume no position.
|
// list, so wrapped groups keep their own styling and consume no position.
|
||||||
let count_lane = |row: usize| graphic_types::graphic::map_groups_to_legacy(content.element_ref(row)).as_vector().map_or(0, |list| list.len());
|
let key = {
|
||||||
let length: usize = (0..content.len()).map(count_lane).sum();
|
let mut keyed = *ctx;
|
||||||
let mut position: usize = (0..lane).map(count_lane).sum();
|
core_types::context::InjectIndex::set_index(&mut keyed, 0);
|
||||||
|
core_types::registry::cache_key(&keyed)
|
||||||
|
};
|
||||||
|
let generation = ctx.arena().generation();
|
||||||
|
let (length, mut position) = {
|
||||||
|
let mut cached = lane_offsets.lock().unwrap_or_else(std::sync::PoisonError::into_inner);
|
||||||
|
if !matches!(cached.as_ref(), Some(entry) if entry.key == key && entry.generation == generation) {
|
||||||
|
let mut offsets = Vec::with_capacity(content.len() + 1);
|
||||||
|
let mut running = 0;
|
||||||
|
offsets.push(running);
|
||||||
|
for row in 0..content.len() {
|
||||||
|
running += graphic_types::graphic::direct_vector_len(content.element_ref(row));
|
||||||
|
offsets.push(running);
|
||||||
|
}
|
||||||
|
*cached = Some(LaneOffsets { key, generation, offsets });
|
||||||
|
}
|
||||||
|
let entry = cached.as_ref().expect("populated above");
|
||||||
|
(entry.offsets[content.len()], entry.offsets[lane])
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(vector_list) = element.as_vector_mut() {
|
if let Some(vector_list) = element.as_vector_mut() {
|
||||||
for index in 0..vector_list.len() {
|
for index in 0..vector_list.len() {
|
||||||
@@ -218,6 +237,16 @@ fn assign_colors_graphic<'e>(
|
|||||||
Ok((element, transform, layer_path))
|
Ok((element, transform, layer_path))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Where each lane's colors start in the level's flattened vector run, so the
|
||||||
|
/// level is counted once per evaluation rather than once per lane. `offsets`
|
||||||
|
/// holds one entry per lane plus the total.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct LaneOffsets {
|
||||||
|
key: u64,
|
||||||
|
generation: u64,
|
||||||
|
offsets: Vec<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn assign_colors_graphic_extent(
|
fn assign_colors_graphic_extent(
|
||||||
content: ListIn<'_, Graphic>,
|
content: ListIn<'_, Graphic>,
|
||||||
|
|||||||
Reference in New Issue
Block a user