Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial GitHub actions CI #7

Merged
merged 10 commits into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Rust

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

env:
CARGO_TERM_COLOR: always

jobs:
check-rs:
runs-on: ubuntu-latest
env:
RUSTFLAGS: "-D warnings"
steps:
- name: Install Protoc
uses: arduino/setup-protoc@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/checkout@v3
- name: Check cargo fmt compliance
run: cargo fmt --all -- --check
- name: Check no rustc warnings
run: cargo check --tests
- name: Check for clippy warnings
run: cargo clippy
- name: Build
run: cargo build --verbose
# # Tests currently fail with `MakeWgpuAdapterError`
# - name: Run tests
# run: cargo test --verbose
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/target
/.idea
/vega-wgpu-renderer/tests/output/
.DS_Store
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,7 @@ image export, and to VegaFusion to support serverside rendering of large marks.
To start with, the most valuable contribution of this project is probably the testing infrastructure. By relying on
vl-convert, a collection of input Vega specs are rendered to PNG and converted to scene graphs. The GPU rendered
PNG images are then compared for similarity to the baselines using structural similarity. See the `gen-test-data`
crate for more information.
crate for more information.

Note: These tests aren't running on GitHub Actions yet due to a `MakeWgpuAdapterError` error that
needs to be diagnosed.
6 changes: 3 additions & 3 deletions gen-test-data/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,21 +82,21 @@ fn main() {
/// Get the image width from the SVG
fn get_svg_width(svg: &str) -> u32 {
let width_re = Regex::new("width=\"(\\d+)\"").unwrap();
let captures = width_re.captures(&svg).expect("Missing width");
let captures = width_re.captures(svg).expect("Missing width");
captures.get(1).unwrap().as_str().parse().unwrap()
}

/// Get the image height from the SVG
fn get_svg_height(svg: &str) -> u32 {
let width_re = Regex::new("height=\"(\\d+)\"").unwrap();
let captures = width_re.captures(&svg).expect("Missing height");
let captures = width_re.captures(svg).expect("Missing height");
captures.get(1).unwrap().as_str().parse().unwrap()
}

/// Get the renderer origin by extracting the first `translate` transform from the SVG
fn get_svg_origin(svg: &str) -> (u32, u32) {
let width_re = Regex::new("translate\\((\\d+),(\\d+)\\)").unwrap();
let captures = width_re.captures(&svg).expect("Missing height");
let captures = width_re.captures(svg).expect("Missing height");
let origin_x: u32 = captures.get(1).unwrap().as_str().parse().unwrap();
let origin_y: u32 = captures.get(2).unwrap().as_str().parse().unwrap();
(origin_x, origin_y)
Expand Down
15 changes: 4 additions & 11 deletions vega-wgpu-renderer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,16 @@ pub mod renderers;
pub mod scene;
pub mod specs;

use std::iter;
use wgpu::util::DeviceExt;

use winit::dpi::{LogicalSize, PhysicalSize, Size};
use winit::dpi::{PhysicalSize, Size};
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
window::{Window, WindowBuilder},
window::WindowBuilder,
};

use crate::renderers::canvas::{Canvas, PngCanvas, WindowCanvas};
use crate::scene::rect::RectInstance;
use crate::renderers::canvas::{Canvas, WindowCanvas};
use crate::scene::scene_graph::SceneGraph;
use crate::scene::symbol::SymbolInstance;
use crate::specs::dims::SceneGraphDims;
use crate::specs::group::GroupItemSpec;
use crate::specs::mark::{MarkContainerSpec, MarkSpec};
use crate::specs::SceneGraphSpec;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
Expand Down Expand Up @@ -81,7 +74,7 @@ pub async fn run() {
.expect("Failed to parse scene graph");

// Save to png
let mut canvas = WindowCanvas::new(window, origin).await.unwrap();
let mut canvas = WindowCanvas::new(window).await.unwrap();

canvas.set_scene(&scene_graph);

Expand Down
36 changes: 16 additions & 20 deletions vega-wgpu-renderer/src/renderers/canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ use crate::renderers::rect::RectShader;
use crate::renderers::rule::RuleShader;
use crate::renderers::symbol::SymbolShader;
use crate::renderers::text::TextMarkRenderer;
use crate::scene::rect::{RectInstance, RectMark};
use crate::scene::rect::RectMark;
use crate::scene::rule::RuleMark;
use crate::scene::scene_graph::{SceneGraph, SceneGroup, SceneMark};
use crate::scene::symbol::{SymbolInstance, SymbolMark};
use crate::scene::symbol::SymbolMark;
use crate::scene::text::TextMark;
use image::imageops::crop_imm;
use wgpu::{
Adapter, Buffer, BufferAddress, BufferDescriptor, BufferUsages, CommandBuffer, CommandEncoder,
Adapter, Buffer, BufferAddress, BufferDescriptor, BufferUsages, CommandBuffer,
CommandEncoderDescriptor, Device, DeviceDescriptor, Extent3d, ImageCopyBuffer,
ImageCopyTexture, ImageDataLayout, LoadOp, MapMode, Operations, Origin3d, PowerPreference,
Queue, RenderPassColorAttachment, RenderPassDescriptor, RequestAdapterOptions, StoreOp,
Expand Down Expand Up @@ -49,8 +49,8 @@ pub trait Canvas {

fn add_symbol_mark(&mut self, mark: &SymbolMark) {
self.add_mark_renderer(MarkRenderer::Geom(GeomMarkRenderer::new(
&self.device(),
self.uniform().clone(),
self.device(),
*self.uniform(),
self.texture_format(),
self.sample_count(),
Box::new(SymbolShader::new(mark.shape)),
Expand All @@ -60,8 +60,8 @@ pub trait Canvas {

fn add_rect_mark(&mut self, mark: &RectMark) {
self.add_mark_renderer(MarkRenderer::Geom(GeomMarkRenderer::new(
&self.device(),
self.uniform().clone(),
self.device(),
*self.uniform(),
self.texture_format(),
self.sample_count(),
Box::new(RectShader::new()),
Expand All @@ -71,8 +71,8 @@ pub trait Canvas {

fn add_rule_mark(&mut self, mark: &RuleMark) {
self.add_mark_renderer(MarkRenderer::Geom(GeomMarkRenderer::new(
&self.device(),
self.uniform().clone(),
self.device(),
*self.uniform(),
self.texture_format(),
self.sample_count(),
Box::new(RuleShader::new()),
Expand All @@ -82,9 +82,9 @@ pub trait Canvas {

fn add_text_mark(&mut self, mark: &TextMark) {
self.add_mark_renderer(MarkRenderer::Text(TextMarkRenderer::new(
&self.device(),
&self.queue(),
self.uniform().clone(),
self.device(),
self.queue(),
*self.uniform(),
self.texture_format(),
self.sample_count(),
mark.instances.clone(),
Expand Down Expand Up @@ -257,11 +257,10 @@ pub struct WindowCanvas {
size: winit::dpi::PhysicalSize<u32>,
marks: Vec<MarkRenderer>,
uniform: CanvasUniform,
origin: [f32; 2],
}

impl WindowCanvas {
pub async fn new(window: Window, origin: [f32; 2]) -> Result<Self, VegaWgpuError> {
pub async fn new(window: Window) -> Result<Self, VegaWgpuError> {
let size = window.inner_size();

let instance = make_wgpu_instance();
Expand Down Expand Up @@ -316,7 +315,6 @@ impl WindowCanvas {
window,
uniform,
marks: Vec::new(),
origin,
})
}

Expand All @@ -328,7 +326,7 @@ impl WindowCanvas {
&self.window
}

pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
pub fn resize(&mut self, _new_size: winit::dpi::PhysicalSize<u32>) {
// if new_size.width > 0 && new_size.height > 0 {
// self.size = new_size;
// self.config.width = new_size.width;
Expand Down Expand Up @@ -433,7 +431,6 @@ pub struct PngCanvas {
uniform: CanvasUniform,
width: f32,
height: f32,
origin: [f32; 2],
pub texture_view: TextureView,
pub output_buffer: Buffer,
pub texture: Texture,
Expand All @@ -443,7 +440,7 @@ pub struct PngCanvas {
}

impl PngCanvas {
pub async fn new(width: f32, height: f32, origin: [f32; 2]) -> Result<Self, VegaWgpuError> {
pub async fn new(width: f32, height: f32) -> Result<Self, VegaWgpuError> {
let instance = make_wgpu_instance();
let adapter = make_wgpu_adapter(&instance, None).await?;
let (device, queue) = request_wgpu_device(&adapter).await?;
Expand Down Expand Up @@ -509,7 +506,6 @@ impl PngCanvas {
width,
height,
uniform,
origin,
texture,
texture_view,
output_buffer,
Expand Down Expand Up @@ -620,7 +616,7 @@ impl PngCanvas {
};

self.output_buffer.unmap();
Ok((img))
Ok(img)
}
}

Expand Down
10 changes: 1 addition & 9 deletions vega-wgpu-renderer/src/renderers/mark.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::renderers::canvas::CanvasUniform;
use crate::renderers::vertex::Vertex;
use crate::scene::rect::RectInstance;
use wgpu::util::DeviceExt;
use wgpu::{CommandBuffer, Device, TextureFormat, TextureView};

Expand All @@ -17,13 +16,10 @@ pub trait MarkShader {
pub struct GeomMarkRenderer {
render_pipeline: wgpu::RenderPipeline,
vertex_buffer: wgpu::Buffer,
num_vertices: u32,
index_buffer: wgpu::Buffer,
num_indices: u32,
instance_buffer: wgpu::Buffer,
num_instances: u32,
uniform_buffer: wgpu::Buffer,
uniform: CanvasUniform,
uniform_bind_group: wgpu::BindGroup,
}

Expand Down Expand Up @@ -126,7 +122,6 @@ impl GeomMarkRenderer {
contents: bytemuck::cast_slice(mark_shader.verts()),
usage: wgpu::BufferUsages::VERTEX,
});
let num_vertices = mark_shader.verts().len() as u32;

let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Index Buffer"),
Expand All @@ -145,13 +140,10 @@ impl GeomMarkRenderer {
Self {
render_pipeline,
vertex_buffer,
num_vertices,
index_buffer,
num_indices,
instance_buffer,
num_instances,
uniform_buffer,
uniform,
uniform_bind_group,
}
}
Expand Down Expand Up @@ -190,6 +182,6 @@ impl GeomMarkRenderer {
render_pass.draw_indexed(0..self.num_indices, 0, 0..self.num_instances);
}

return mark_encoder.finish();
mark_encoder.finish()
}
}
6 changes: 6 additions & 0 deletions vega-wgpu-renderer/src/renderers/rect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ pub struct RectShader {
fragment_entry_point: String,
}

impl Default for RectShader {
fn default() -> Self {
Self::new()
}
}

impl RectShader {
pub fn new() -> Self {
Self {
Expand Down
6 changes: 6 additions & 0 deletions vega-wgpu-renderer/src/renderers/rule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ pub struct RuleShader {
fragment_entry_point: String,
}

impl Default for RuleShader {
fn default() -> Self {
Self::new()
}
}

impl RuleShader {
pub fn new() -> Self {
Self {
Expand Down
4 changes: 2 additions & 2 deletions vega-wgpu-renderer/src/renderers/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ impl SymbolShader {
SymbolShape::Triangle => {
let r = 0.5;
let h = r * sqrt3 / 2.0;
let o = (h - r * tan30);
let o = h - r * tan30;
Self {
verts: vec![
Vertex {
Expand Down Expand Up @@ -279,7 +279,7 @@ impl SymbolShader {
SymbolShape::Wedge => {
let r = 0.5;
let h = r * sqrt3 / 2.0;
let o = (h - r * tan30);
let o = h - r * tan30;
let b = r / 4.0;
Self {
verts: vec![
Expand Down
20 changes: 9 additions & 11 deletions vega-wgpu-renderer/src/renderers/text.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use crate::renderers::canvas::CanvasUniform;
use crate::renderers::mark::MarkShader;
use crate::scene::text::TextInstance;
use crate::specs::text::{FontWeightNameSpec, FontWeightSpec, TextAlignSpec, TextBaselineSpec};
use glyphon::cosmic_text::Align;
use glyphon::{
Attrs, Buffer, Color, Family, FontSystem, Metrics, Resolution, Shaping, SwashCache, TextArea,
TextAtlas, TextBounds, TextRenderer, Weight,
Expand Down Expand Up @@ -30,12 +28,12 @@ impl TextMarkRenderer {
sample_count: u32,
instances: Vec<TextInstance>,
) -> Self {
let mut font_system = FontSystem::new();
let mut cache = SwashCache::new();
let font_system = FontSystem::new();
let cache = SwashCache::new();
let mut atlas = TextAtlas::new(device, queue, texture_format);
let mut text_renderer = TextRenderer::new(
let text_renderer = TextRenderer::new(
&mut atlas,
&device,
device,
MultisampleState {
count: sample_count,
mask: !0,
Expand Down Expand Up @@ -106,7 +104,7 @@ impl TextMarkRenderer {
.iter()
.zip(&self.instances)
.map(|(buffer, instance)| {
let (width, height) = measure(&buffer);
let (width, height) = measure(buffer);

let left = match instance.align {
TextAlignSpec::Left => instance.position[0],
Expand All @@ -125,7 +123,7 @@ impl TextMarkRenderer {
};

TextArea {
buffer: &buffer,
buffer,
left,
top,
scale: 1.0,
Expand All @@ -146,8 +144,8 @@ impl TextMarkRenderer {

self.text_renderer
.prepare(
&device,
&queue,
device,
queue,
&mut self.font_system,
&mut self.atlas,
Resolution {
Expand All @@ -166,7 +164,7 @@ impl TextMarkRenderer {
let mut pass = encoder.begin_render_pass(&RenderPassDescriptor {
label: None,
color_attachments: &[Some(RenderPassColorAttachment {
view: &texture_view,
view: texture_view,
resolve_target,
ops: Operations {
load: wgpu::LoadOp::Load,
Expand Down
Loading