mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-10 12:41:30 +11:00
Allow arbitrary output sizes (#206)
* Support basic resizing * Fix resizing
This commit is contained in:
parent
98e0499b31
commit
0755e8bfaa
|
@ -20,6 +20,7 @@ use std::{fs::File, io::BufWriter};
|
|||
|
||||
use engine::Engine;
|
||||
|
||||
use render::next_multiple_of;
|
||||
use wgpu::{Device, Limits, Queue};
|
||||
|
||||
mod debug;
|
||||
|
@ -30,7 +31,7 @@ mod render;
|
|||
mod shaders;
|
||||
mod test_scene;
|
||||
|
||||
async fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||
async fn run(dimensions: &Dimensions) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let instance = wgpu::Instance::new(wgpu::Backends::PRIMARY);
|
||||
let adapter = instance.request_adapter(&Default::default()).await.unwrap();
|
||||
let features = adapter.features();
|
||||
|
@ -47,7 +48,7 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
|
|||
)
|
||||
.await?;
|
||||
let mut engine = Engine::new();
|
||||
do_render(&device, &queue, &mut engine).await?;
|
||||
do_render(&device, &queue, &mut engine, dimensions).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -69,6 +70,7 @@ async fn do_render(
|
|||
device: &Device,
|
||||
queue: &Queue,
|
||||
engine: &mut Engine,
|
||||
dimensions: &Dimensions,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
#[allow(unused)]
|
||||
let shaders = shaders::init_shaders(device, engine)?;
|
||||
|
@ -76,7 +78,7 @@ async fn do_render(
|
|||
let scene = test_scene::gen_test_scene();
|
||||
//test_scene::dump_scene_info(&scene);
|
||||
//let (recording, buf) = render::render(&scene, &shaders);
|
||||
let (recording, buf) = render::render_full(&scene, &full_shaders);
|
||||
let (recording, buf) = render::render_full(&scene, &full_shaders, dimensions);
|
||||
let downloads = engine.run_recording(&device, &queue, &recording)?;
|
||||
let mapped = downloads.map();
|
||||
device.poll(wgpu::Maintain::Wait);
|
||||
|
@ -87,14 +89,43 @@ async fn do_render(
|
|||
} else {
|
||||
let file = File::create("image.png")?;
|
||||
let w = BufWriter::new(file);
|
||||
let mut encoder = png::Encoder::new(w, 1024, 1024);
|
||||
let mut encoder = png::Encoder::new(w, dimensions.width, dimensions.height);
|
||||
encoder.set_color(png::ColorType::Rgba);
|
||||
let mut writer = encoder.write_header()?;
|
||||
let expected_size = (dimensions.width * dimensions.height * 4) as usize;
|
||||
|
||||
let new_width = next_multiple_of(dimensions.width, 16) as usize;
|
||||
|
||||
if expected_size == buf.len() {
|
||||
writer.write_image_data(&buf)?;
|
||||
} else {
|
||||
let mut output = Vec::<u8>::with_capacity(expected_size * 4);
|
||||
for height in 0..(dimensions.height as usize) {
|
||||
output.extend_from_slice(
|
||||
&buf[height * new_width * 4..][..dimensions.width as usize * 4],
|
||||
);
|
||||
}
|
||||
writer.write_image_data(&output)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
pollster::block_on(run()).unwrap();
|
||||
pub struct Dimensions {
|
||||
width: u32,
|
||||
height: u32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = std::env::args();
|
||||
args.next();
|
||||
let width = args
|
||||
.next()
|
||||
.and_then(|it| it.parse::<u32>().ok())
|
||||
.unwrap_or(1024);
|
||||
let height = args
|
||||
.next()
|
||||
.and_then(|it| it.parse::<u32>().ok())
|
||||
.unwrap_or(1024);
|
||||
pollster::block_on(run(&Dimensions { width, height })).unwrap();
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ use piet_scene::Scene;
|
|||
use crate::{
|
||||
engine::{BufProxy, Recording, ResourceProxy},
|
||||
shaders::{self, FullShaders, Shaders},
|
||||
Dimensions,
|
||||
};
|
||||
|
||||
const TAG_MONOID_SIZE: u64 = 12;
|
||||
|
@ -52,7 +53,14 @@ fn size_to_words(byte_size: usize) -> u32 {
|
|||
(byte_size / std::mem::size_of::<u32>()) as u32
|
||||
}
|
||||
|
||||
pub fn render(scene: &Scene, shaders: &Shaders) -> (Recording, BufProxy) {
|
||||
pub const fn next_multiple_of(val: u32, rhs: u32) -> u32 {
|
||||
match val % rhs {
|
||||
0 => val,
|
||||
r => val + (rhs - r),
|
||||
}
|
||||
}
|
||||
|
||||
fn render(scene: &Scene, shaders: &Shaders) -> (Recording, BufProxy) {
|
||||
let mut recording = Recording::default();
|
||||
let data = scene.data();
|
||||
let n_pathtag = data.tag_stream.len();
|
||||
|
@ -125,7 +133,11 @@ pub fn render(scene: &Scene, shaders: &Shaders) -> (Recording, BufProxy) {
|
|||
(recording, out_buf)
|
||||
}
|
||||
|
||||
pub fn render_full(scene: &Scene, shaders: &FullShaders) -> (Recording, BufProxy) {
|
||||
pub fn render_full(
|
||||
scene: &Scene,
|
||||
shaders: &FullShaders,
|
||||
dimensions: &Dimensions,
|
||||
) -> (Recording, BufProxy) {
|
||||
let mut recording = Recording::default();
|
||||
let mut ramps = crate::ramp::RampCache::default();
|
||||
let mut drawdata_patches: Vec<(usize, u32)> = vec![];
|
||||
|
@ -192,9 +204,14 @@ pub fn render_full(scene: &Scene, shaders: &FullShaders) -> (Recording, BufProxy
|
|||
// TODO: calculate for real when we do rectangles
|
||||
let n_drawobj = n_path;
|
||||
let n_clip = data.n_clip;
|
||||
|
||||
let new_width = next_multiple_of(dimensions.width, 16);
|
||||
let new_height = next_multiple_of(dimensions.width, 16);
|
||||
|
||||
let config = Config {
|
||||
width_in_tiles: 64,
|
||||
height_in_tiles: 64,
|
||||
// TODO: Replace with div_ceil once stable
|
||||
width_in_tiles: new_width / 16,
|
||||
height_in_tiles: new_height / 16,
|
||||
n_drawobj,
|
||||
n_path,
|
||||
n_clip,
|
||||
|
|
Loading…
Reference in a new issue