Skip to content

Commit

Permalink
Instance refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
jonmmease committed Nov 30, 2024
1 parent 2b3c633 commit 25e0251
Show file tree
Hide file tree
Showing 18 changed files with 2,228 additions and 1,036 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ tracing-subscriber = "0.3.18"
rayon = "1.8.1"
winit = "0.30.5"
wgpu = "23.0.1"

arrow = "53.3.0"
itertools = "0.13.0"
2 changes: 1 addition & 1 deletion avenger-wgpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ cfg-if = "1"
winit = { workspace = true }
wgpu = { workspace = true }
pollster = "0.4.0"
itertools = "0.13.0"
itertools = { workspace = true }
image = { workspace = true }
futures-intrusive = "^0.5"
etagere = "0.2.10"
Expand Down
993 changes: 430 additions & 563 deletions avenger-wgpu/src/marks/multi.rs

Large diffs are not rendered by default.

48 changes: 22 additions & 26 deletions avenger-wgpu/src/marks/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use crate::error::AvengerWgpuError;
use crate::marks::instanced_mark::{InstancedMarkBatch, InstancedMarkShader};
use avenger::marks::path::PathTransform;
use avenger::marks::symbol::SymbolMark;
use itertools::izip;
use lyon::lyon_tessellation::{
BuffersBuilder, FillVertex, FillVertexConstructor, StrokeVertex, StrokeVertexConstructor,
};
Expand Down Expand Up @@ -62,7 +61,7 @@ impl SymbolVertex {

#[repr(C)]
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
pub struct SymbolInstance {
pub struct SymbolShaderInstance {
pub position: [f32; 2],
pub fill_color: [f32; 4],
pub stroke_color: [f32; 4],
Expand All @@ -84,31 +83,28 @@ const INSTANCE_ATTRIBUTES: [wgpu::VertexAttribute; 7] = wgpu::vertex_attr_array!
10 => Uint32, // shape_index
];

impl SymbolInstance {
impl SymbolShaderInstance {
pub fn from_spec(
mark: &SymbolMark,
max_size: f32,
) -> (Vec<SymbolInstance>, Option<image::DynamicImage>, Extent3d) {
) -> (
Vec<SymbolShaderInstance>,
Option<image::DynamicImage>,
Extent3d,
) {
let max_scale = max_size.sqrt();
let stroke_width = mark.stroke_width.unwrap_or(0.0);
let mut instances: Vec<SymbolInstance> = Vec::new();
for (x, y, fill, size, stroke, angle, shape_index) in izip!(
mark.x_iter(),
mark.y_iter(),
mark.fill_iter(),
mark.size_iter(),
mark.stroke_iter(),
mark.angle_iter(),
mark.shape_index_iter(),
) {
instances.push(SymbolInstance {
position: [*x, *y],
fill_color: fill.color_or_transparent(),
stroke_color: stroke.color_or_transparent(),
stroke_width,
relative_scale: (*size).sqrt() / max_scale,
angle: *angle,
shape_index: (*shape_index) as u32,
let mut instances: Vec<SymbolShaderInstance> = Vec::new();

for instance in mark.instances() {
instances.push(SymbolShaderInstance {
position: [instance.x, instance.y],
fill_color: instance.fill.color_or_transparent(),
stroke_color: instance.stroke.color_or_transparent(),
stroke_width: stroke_width,
relative_scale: (instance.size).sqrt() / max_scale,
angle: instance.angle,
shape_index: (instance.shape_index) as u32,
});
}

Expand All @@ -119,7 +115,7 @@ impl SymbolInstance {
pub struct SymbolShader {
verts: Vec<SymbolVertex>,
indices: Vec<u16>,
instances: Vec<SymbolInstance>,
instances: Vec<SymbolShaderInstance>,
uniform: SymbolUniform,
batches: Vec<InstancedMarkBatch>,
texture_size: Extent3d,
Expand Down Expand Up @@ -170,7 +166,7 @@ impl SymbolShader {
verts.extend(buffers.vertices);
indices.extend(buffers.indices.into_iter().map(|i| i + index_offset));
}
let (instances, img, texture_size) = SymbolInstance::from_spec(mark, max_size);
let (instances, img, texture_size) = SymbolShaderInstance::from_spec(mark, max_size);
let batches = vec![InstancedMarkBatch {
instances_range: 0..instances.len() as u32,
image: img,
Expand All @@ -190,7 +186,7 @@ impl SymbolShader {
}

impl InstancedMarkShader for SymbolShader {
type Instance = SymbolInstance;
type Instance = SymbolShaderInstance;
type Vertex = SymbolVertex;
type Uniform = SymbolUniform;

Expand Down Expand Up @@ -232,7 +228,7 @@ impl InstancedMarkShader for SymbolShader {

fn instance_desc(&self) -> wgpu::VertexBufferLayout<'static> {
wgpu::VertexBufferLayout {
array_stride: std::mem::size_of::<SymbolInstance>() as wgpu::BufferAddress,
array_stride: std::mem::size_of::<SymbolShaderInstance>() as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Instance,
attributes: &INSTANCE_ATTRIBUTES,
}
Expand Down
3 changes: 3 additions & 0 deletions avenger/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ workspace = true
workspace = true
features = [ "serialization",]

[dependencies.itertools]
workspace = true

[dependencies.image]
workspace = true
features = [ "png",]
Expand Down
166 changes: 113 additions & 53 deletions avenger/src/marks/arc.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::marks::value::{ColorOrGradient, EncodingValue, Gradient};
use itertools::izip;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand All @@ -8,6 +9,10 @@ pub struct ArcMark {
pub clip: bool,
pub len: u32,
pub gradients: Vec<Gradient>,
pub indices: Option<Vec<usize>>,
pub zindex: Option<i32>,

// Encodings
pub x: EncodingValue<f32>,
pub y: EncodingValue<f32>,
pub start_angle: EncodingValue<f32>,
Expand All @@ -19,78 +24,133 @@ pub struct ArcMark {
pub fill: EncodingValue<ColorOrGradient>,
pub stroke: EncodingValue<ColorOrGradient>,
pub stroke_width: EncodingValue<f32>,
pub indices: Option<Vec<usize>>,
pub zindex: Option<i32>,
}

impl ArcMark {
pub fn x_iter(&self) -> Box<dyn Iterator<Item = &f32> + '_> {
self.x.as_iter(self.len as usize, self.indices.as_ref())
}
pub fn y_iter(&self) -> Box<dyn Iterator<Item = &f32> + '_> {
self.y.as_iter(self.len as usize, self.indices.as_ref())
}
pub fn start_angle_iter(&self) -> Box<dyn Iterator<Item = &f32> + '_> {
self.start_angle
.as_iter(self.len as usize, self.indices.as_ref())
}
pub fn end_angle_iter(&self) -> Box<dyn Iterator<Item = &f32> + '_> {
self.end_angle
.as_iter(self.len as usize, self.indices.as_ref())
}
pub fn outer_radius_iter(&self) -> Box<dyn Iterator<Item = &f32> + '_> {
self.outer_radius
.as_iter(self.len as usize, self.indices.as_ref())
}
pub fn inner_radius_iter(&self) -> Box<dyn Iterator<Item = &f32> + '_> {
self.inner_radius
.as_iter(self.len as usize, self.indices.as_ref())
}
pub fn pad_angle_iter(&self) -> Box<dyn Iterator<Item = &f32> + '_> {
self.pad_angle
.as_iter(self.len as usize, self.indices.as_ref())
}
pub fn corner_radius_iter(&self) -> Box<dyn Iterator<Item = &f32> + '_> {
self.corner_radius
.as_iter(self.len as usize, self.indices.as_ref())
}
pub fn fill_iter(&self) -> Box<dyn Iterator<Item = &ColorOrGradient> + '_> {
self.fill.as_iter(self.len as usize, self.indices.as_ref())
}
pub fn stroke_iter(&self) -> Box<dyn Iterator<Item = &ColorOrGradient> + '_> {
self.stroke
.as_iter(self.len as usize, self.indices.as_ref())
}
pub fn stroke_width_iter(&self) -> Box<dyn Iterator<Item = &f32> + '_> {
self.stroke_width
.as_iter(self.len as usize, self.indices.as_ref())
pub fn instances(&self) -> Box<dyn Iterator<Item = ArcMarkInstance> + '_> {
let n = self.len as usize;
let inds = self.indices.as_ref();
Box::new(
izip!(
self.x.as_iter(n, inds),
self.y.as_iter(n, inds),
self.start_angle.as_iter(n, inds),
self.end_angle.as_iter(n, inds),
self.outer_radius.as_iter(n, inds),
self.inner_radius.as_iter(n, inds),
self.pad_angle.as_iter(n, inds),
self.corner_radius.as_iter(n, inds),
self.fill.as_iter(n, inds),
self.stroke.as_iter(n, inds),
self.stroke_width.as_iter(n, inds),
)
.map(
|(
x,
y,
start_angle,
end_angle,
outer_radius,
inner_radius,
pad_angle,
corner_radius,
fill_color,
stroke_color,
stroke_width,
)| ArcMarkInstance {
x: *x,
y: *y,
start_angle: *start_angle,
end_angle: *end_angle,
outer_radius: *outer_radius,
inner_radius: *inner_radius,
pad_angle: *pad_angle,
corner_radius: *corner_radius,
fill_color: fill_color.clone(),
stroke_color: stroke_color.clone(),
stroke_width: *stroke_width,
},
),
)
}
}

impl Default for ArcMark {
fn default() -> Self {
let default_instance = ArcMarkInstance::default();
Self {
name: "arc_mark".to_string(),
clip: true,
len: 1,
gradients: vec![],
x: EncodingValue::Scalar { value: 0.0 },
y: EncodingValue::Scalar { value: 0.0 },
start_angle: EncodingValue::Scalar { value: 0.0 },
end_angle: EncodingValue::Scalar { value: 0.0 },
outer_radius: EncodingValue::Scalar { value: 0.0 },
inner_radius: EncodingValue::Scalar { value: 0.0 },
pad_angle: EncodingValue::Scalar { value: 0.0 },
corner_radius: EncodingValue::Scalar { value: 0.0 },
x: EncodingValue::Scalar {
value: default_instance.x,
},
y: EncodingValue::Scalar {
value: default_instance.y,
},
start_angle: EncodingValue::Scalar {
value: default_instance.start_angle,
},
end_angle: EncodingValue::Scalar {
value: default_instance.end_angle,
},
outer_radius: EncodingValue::Scalar {
value: default_instance.outer_radius,
},
inner_radius: EncodingValue::Scalar {
value: default_instance.inner_radius,
},
pad_angle: EncodingValue::Scalar {
value: default_instance.pad_angle,
},
corner_radius: EncodingValue::Scalar {
value: default_instance.corner_radius,
},
fill: EncodingValue::Scalar {
value: ColorOrGradient::Color([0.0, 0.0, 0.0, 1.0]),
value: default_instance.fill_color,
},
stroke: EncodingValue::Scalar {
value: ColorOrGradient::Color([0.0, 0.0, 0.0, 0.0]),
value: default_instance.stroke_color,
},
stroke_width: EncodingValue::Scalar {
value: default_instance.stroke_width,
},
stroke_width: EncodingValue::Scalar { value: 0.0 },
indices: None,
zindex: None,
}
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ArcMarkInstance {
pub x: f32,
pub y: f32,
pub start_angle: f32,
pub end_angle: f32,
pub outer_radius: f32,
pub inner_radius: f32,
pub pad_angle: f32,
pub corner_radius: f32,
pub fill_color: ColorOrGradient,
pub stroke_color: ColorOrGradient,
pub stroke_width: f32,
}

impl Default for ArcMarkInstance {
fn default() -> Self {
Self {
x: 0.0,
y: 0.0,
start_angle: 0.0,
end_angle: 0.0,
outer_radius: 0.0,
inner_radius: 0.0,
pad_angle: 0.0,
corner_radius: 0.0,
fill_color: ColorOrGradient::Color([0.0, 0.0, 0.0, 1.0]),
stroke_color: ColorOrGradient::Color([0.0, 0.0, 0.0, 0.0]),
stroke_width: 0.0,
}
}
}
Loading

0 comments on commit 25e0251

Please sign in to comment.