mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-29 23:28:12 +08:00
Resolve paint and transform columns once per lane loop
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
use crate::Color;
|
use crate::Color;
|
||||||
use crate::lane::LaneSource;
|
use crate::lane::{LaneColumn, LaneSource};
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Default, Debug, PartialEq)]
|
#[derive(Clone, Copy, Default, Debug, PartialEq)]
|
||||||
@@ -61,9 +61,10 @@ where
|
|||||||
{
|
{
|
||||||
let mut combined_bounds = None;
|
let mut combined_bounds = None;
|
||||||
|
|
||||||
|
let transforms = source.column::<crate::attribute::Transform>();
|
||||||
for lane in 0..source.lane_count() {
|
for lane in 0..source.lane_count() {
|
||||||
let Some(element) = source.element(lane) else { continue };
|
let Some(element) = source.element(lane) else { continue };
|
||||||
let lane_transform: DAffine2 = source.attr::<crate::attribute::Transform>(lane);
|
let lane_transform: DAffine2 = transforms.get(lane);
|
||||||
match element.bounding_box(transform * lane_transform, include_stroke) {
|
match element.bounding_box(transform * lane_transform, include_stroke) {
|
||||||
RenderBoundingBox::None => continue,
|
RenderBoundingBox::None => continue,
|
||||||
RenderBoundingBox::Infinite => return RenderBoundingBox::Infinite,
|
RenderBoundingBox::Infinite => return RenderBoundingBox::Infinite,
|
||||||
@@ -90,9 +91,10 @@ where
|
|||||||
let mut combined_bounds = None;
|
let mut combined_bounds = None;
|
||||||
let mut any_infinite = false;
|
let mut any_infinite = false;
|
||||||
|
|
||||||
|
let transforms = source.column::<crate::attribute::Transform>();
|
||||||
for lane in 0..source.lane_count() {
|
for lane in 0..source.lane_count() {
|
||||||
let Some(element) = source.element(lane) else { continue };
|
let Some(element) = source.element(lane) else { continue };
|
||||||
let lane_transform: DAffine2 = source.attr::<crate::attribute::Transform>(lane);
|
let lane_transform: DAffine2 = transforms.get(lane);
|
||||||
match element.thumbnail_bounding_box(transform * lane_transform, include_stroke) {
|
match element.thumbnail_bounding_box(transform * lane_transform, include_stroke) {
|
||||||
RenderBoundingBox::None => continue,
|
RenderBoundingBox::None => continue,
|
||||||
RenderBoundingBox::Infinite => any_infinite = true,
|
RenderBoundingBox::Infinite => any_infinite = true,
|
||||||
|
|||||||
@@ -248,16 +248,32 @@ pub struct LanePaint<'a> {
|
|||||||
impl<'a> LanePaint<'a> {
|
impl<'a> LanePaint<'a> {
|
||||||
pub const NONE: Self = Self { fill: None, stroke: None };
|
pub const NONE: Self = Self { fill: None, stroke: None };
|
||||||
|
|
||||||
/// The lane's present, non-blank paint.
|
pub fn is_present(&self) -> bool {
|
||||||
pub fn read<S: LaneSource>(source: &'a S, index: usize) -> Self {
|
self.fill.is_some() || self.stroke.is_some()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A source's fill and stroke columns, resolved once for per-lane reads.
|
||||||
|
pub struct PaintColumns<'a, S: LaneSource + 'a> {
|
||||||
|
fill: S::Column<'a, Fill>,
|
||||||
|
stroke: S::Column<'a, Stroke>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, S: LaneSource> PaintColumns<'a, S> {
|
||||||
|
pub fn new(source: &'a S) -> Self {
|
||||||
Self {
|
Self {
|
||||||
fill: paint_graphics::<Fill, _>(source, index),
|
fill: source.column::<Fill>(),
|
||||||
stroke: paint_graphics::<Stroke, _>(source, index),
|
stroke: source.column::<Stroke>(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_present(&self) -> bool {
|
/// The lane's present, non-blank paint.
|
||||||
self.fill.is_some() || self.stroke.is_some()
|
pub fn read(&self, lane: usize) -> LanePaint<'a> {
|
||||||
|
let present = |value: Option<Option<&'a List<Graphic>>>| value.flatten().filter(|list| is_paint_present(list));
|
||||||
|
LanePaint {
|
||||||
|
fill: present(self.fill.try_get(lane)),
|
||||||
|
stroke: present(self.stroke.try_get(lane)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ use dyn_any::DynAny;
|
|||||||
use glam::{DAffine2, DMat2, DVec2};
|
use glam::{DAffine2, DMat2, DVec2};
|
||||||
use graphene_hash::CacheHashWrapper;
|
use graphene_hash::CacheHashWrapper;
|
||||||
use graphene_resource::Resource;
|
use graphene_resource::Resource;
|
||||||
use graphic_types::graphic::{LanePaint, PaintOverlay, group_to_legacy_list, has_paint, is_paint_present, paint_graphics, set_paint_attribute, vector_can_reduce_to_clip_path};
|
use graphic_types::graphic::{LanePaint, PaintColumns, PaintOverlay, group_to_legacy_list, has_paint, is_paint_present, paint_graphics, set_paint_attribute, vector_can_reduce_to_clip_path};
|
||||||
use graphic_types::markers::{EditorMergedLayers, Fill, Stroke};
|
use graphic_types::markers::{EditorMergedLayers, Fill, Stroke};
|
||||||
use graphic_types::raster_types::{BitmapMut, CPU, GPU, Image, Raster, Texture};
|
use graphic_types::raster_types::{BitmapMut, CPU, GPU, Image, Raster, Texture};
|
||||||
use graphic_types::vector_types::gradient::{GradientStops, GradientType};
|
use graphic_types::vector_types::gradient::{GradientStops, GradientType};
|
||||||
@@ -626,20 +626,13 @@ struct PaintReach<'a> {
|
|||||||
impl<'a> PaintReach<'a> {
|
impl<'a> PaintReach<'a> {
|
||||||
const NONE: Self = Self { paint: LanePaint::NONE, hops: 0 };
|
const NONE: Self = Self { paint: LanePaint::NONE, hops: 0 };
|
||||||
|
|
||||||
fn read<S: LaneSource>(source: &'a S, index: usize) -> Self {
|
|
||||||
Self {
|
|
||||||
paint: LanePaint::read(source, index),
|
|
||||||
hops: 2,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The lane's effective reach: an inherited paint stays authoritative
|
/// The lane's effective reach: an inherited paint stays authoritative
|
||||||
/// (lane paint below a push's origin is inert in the legacy model), an
|
/// (lane paint below a push's origin is inert in the legacy model), an
|
||||||
/// absent one reads the lane's own paint.
|
/// absent one reads the lane's own paint.
|
||||||
fn for_lane<S: LaneSource>(self, source: &'a S, index: usize) -> Self {
|
fn for_lane<S: LaneSource>(self, columns: &PaintColumns<'a, S>, index: usize) -> Self {
|
||||||
match self.paint.is_present() {
|
match self.paint.is_present() {
|
||||||
true => self,
|
true => self,
|
||||||
false => Self::read(source, index),
|
false => Self { paint: columns.read(index), hops: 2 },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1109,6 +1102,7 @@ fn render_graphic_svg<S: LaneSource<Element = Graphic>>(source: &S, render: &mut
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render_graphic_svg_with<'a, S: LaneSource<Element = Graphic>>(source: &'a S, inherited: PaintReach<'a>, render: &mut SvgRender, render_params: &RenderParams) {
|
fn render_graphic_svg_with<'a, S: LaneSource<Element = Graphic>>(source: &'a S, inherited: PaintReach<'a>, render: &mut SvgRender, render_params: &RenderParams) {
|
||||||
|
let paint_columns = PaintColumns::new(source);
|
||||||
let mut mask_state = None;
|
let mut mask_state = None;
|
||||||
|
|
||||||
for index in 0..source.lane_count() {
|
for index in 0..source.lane_count() {
|
||||||
@@ -1117,7 +1111,7 @@ fn render_graphic_svg_with<'a, S: LaneSource<Element = Graphic>>(source: &'a S,
|
|||||||
let opacity_attr: f64 = source.attr::<Opacity>(index);
|
let opacity_attr: f64 = source.attr::<Opacity>(index);
|
||||||
let opacity_fill_attr: f64 = source.attr::<OpacityFill>(index);
|
let opacity_fill_attr: f64 = source.attr::<OpacityFill>(index);
|
||||||
let element = source.element(index).unwrap();
|
let element = source.element(index).unwrap();
|
||||||
let reach = inherited.for_lane(source, index);
|
let reach = inherited.for_lane(&paint_columns, index);
|
||||||
|
|
||||||
render.parent_tag(
|
render.parent_tag(
|
||||||
"g",
|
"g",
|
||||||
@@ -1170,6 +1164,7 @@ fn render_graphic_vello<S: LaneSource<Element = Graphic>>(source: &S, scene: &mu
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render_graphic_vello_with<'a, S: LaneSource<Element = Graphic>>(source: &'a S, inherited: PaintReach<'a>, scene: &mut Scene, transform: DAffine2, context: &mut RenderContext, render_params: &RenderParams) {
|
fn render_graphic_vello_with<'a, S: LaneSource<Element = Graphic>>(source: &'a S, inherited: PaintReach<'a>, scene: &mut Scene, transform: DAffine2, context: &mut RenderContext, render_params: &RenderParams) {
|
||||||
|
let paint_columns = PaintColumns::new(source);
|
||||||
let mut mask_element_and_transform = None;
|
let mut mask_element_and_transform = None;
|
||||||
|
|
||||||
for index in 0..source.lane_count() {
|
for index in 0..source.lane_count() {
|
||||||
@@ -1179,7 +1174,7 @@ fn render_graphic_vello_with<'a, S: LaneSource<Element = Graphic>>(source: &'a S
|
|||||||
let opacity_attr: f64 = source.attr::<Opacity>(index);
|
let opacity_attr: f64 = source.attr::<Opacity>(index);
|
||||||
let opacity_fill_attr: f64 = source.attr::<OpacityFill>(index);
|
let opacity_fill_attr: f64 = source.attr::<OpacityFill>(index);
|
||||||
let element = source.element(index).unwrap();
|
let element = source.element(index).unwrap();
|
||||||
let reach = inherited.for_lane(source, index);
|
let reach = inherited.for_lane(&paint_columns, index);
|
||||||
|
|
||||||
let mut layer = false;
|
let mut layer = false;
|
||||||
|
|
||||||
@@ -1253,12 +1248,13 @@ fn collect_graphic_metadata<S: LaneSource<Element = Graphic>>(source: &S, metada
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn collect_graphic_metadata_with<'a, S: LaneSource<Element = Graphic>>(source: &'a S, inherited: PaintReach<'a>, metadata: &mut RenderMetadata, footprint: Footprint, element_id: Option<NodeId>) {
|
fn collect_graphic_metadata_with<'a, S: LaneSource<Element = Graphic>>(source: &'a S, inherited: PaintReach<'a>, metadata: &mut RenderMetadata, footprint: Footprint, element_id: Option<NodeId>) {
|
||||||
|
let paint_columns = PaintColumns::new(source);
|
||||||
for index in 0..source.lane_count() {
|
for index in 0..source.lane_count() {
|
||||||
let item_transform: DAffine2 = source.attr::<Transform>(index);
|
let item_transform: DAffine2 = source.attr::<Transform>(index);
|
||||||
let layer_path: &[NodeId] = source.attr::<EditorLayerPath>(index);
|
let layer_path: &[NodeId] = source.attr::<EditorLayerPath>(index);
|
||||||
let layer = layer_path.last().copied();
|
let layer = layer_path.last().copied();
|
||||||
let element = source.element(index).unwrap();
|
let element = source.element(index).unwrap();
|
||||||
let reach = inherited.for_lane(source, index);
|
let reach = inherited.for_lane(&paint_columns, index);
|
||||||
|
|
||||||
let mut footprint = footprint;
|
let mut footprint = footprint;
|
||||||
footprint.transform *= item_transform;
|
footprint.transform *= item_transform;
|
||||||
@@ -1278,7 +1274,7 @@ fn collect_graphic_metadata_with<'a, S: LaneSource<Element = Graphic>>(source: &
|
|||||||
for index in 0..source.lane_count() {
|
for index in 0..source.lane_count() {
|
||||||
let item_transform: DAffine2 = source.attr::<Transform>(index);
|
let item_transform: DAffine2 = source.attr::<Transform>(index);
|
||||||
let element = source.element(index).unwrap();
|
let element = source.element(index).unwrap();
|
||||||
let reach = inherited.for_lane(source, index);
|
let reach = inherited.for_lane(&paint_columns, index);
|
||||||
|
|
||||||
let mut new_click_targets = Vec::new();
|
let mut new_click_targets = Vec::new();
|
||||||
add_element_upstream_click_targets(element, reach, &mut new_click_targets);
|
add_element_upstream_click_targets(element, reach, &mut new_click_targets);
|
||||||
@@ -1307,10 +1303,11 @@ fn add_graphic_upstream_click_targets<S: LaneSource<Element = Graphic>>(source:
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add_graphic_upstream_click_targets_with<'a, S: LaneSource<Element = Graphic>>(source: &'a S, inherited: PaintReach<'a>, click_targets: &mut Vec<ClickTarget>) {
|
fn add_graphic_upstream_click_targets_with<'a, S: LaneSource<Element = Graphic>>(source: &'a S, inherited: PaintReach<'a>, click_targets: &mut Vec<ClickTarget>) {
|
||||||
|
let paint_columns = PaintColumns::new(source);
|
||||||
for index in 0..source.lane_count() {
|
for index in 0..source.lane_count() {
|
||||||
let item_transform: DAffine2 = source.attr::<Transform>(index);
|
let item_transform: DAffine2 = source.attr::<Transform>(index);
|
||||||
let element = source.element(index).unwrap();
|
let element = source.element(index).unwrap();
|
||||||
let reach = inherited.for_lane(source, index);
|
let reach = inherited.for_lane(&paint_columns, index);
|
||||||
let mut new_click_targets = Vec::new();
|
let mut new_click_targets = Vec::new();
|
||||||
|
|
||||||
add_element_upstream_click_targets(element, reach, &mut new_click_targets);
|
add_element_upstream_click_targets(element, reach, &mut new_click_targets);
|
||||||
@@ -1328,10 +1325,11 @@ fn add_graphic_upstream_outline_targets<S: LaneSource<Element = Graphic>>(source
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add_graphic_upstream_outline_targets_with<'a, S: LaneSource<Element = Graphic>>(source: &'a S, inherited: PaintReach<'a>, outlines: &mut Vec<ClickTarget>) {
|
fn add_graphic_upstream_outline_targets_with<'a, S: LaneSource<Element = Graphic>>(source: &'a S, inherited: PaintReach<'a>, outlines: &mut Vec<ClickTarget>) {
|
||||||
|
let paint_columns = PaintColumns::new(source);
|
||||||
for index in 0..source.lane_count() {
|
for index in 0..source.lane_count() {
|
||||||
let item_transform: DAffine2 = source.attr::<Transform>(index);
|
let item_transform: DAffine2 = source.attr::<Transform>(index);
|
||||||
let element = source.element(index).unwrap();
|
let element = source.element(index).unwrap();
|
||||||
let reach = inherited.for_lane(source, index);
|
let reach = inherited.for_lane(&paint_columns, index);
|
||||||
let mut new_outlines = Vec::new();
|
let mut new_outlines = Vec::new();
|
||||||
|
|
||||||
add_element_upstream_outline_targets(element, reach, &mut new_outlines);
|
add_element_upstream_outline_targets(element, reach, &mut new_outlines);
|
||||||
|
|||||||
Reference in New Issue
Block a user