wip
This commit is contained in:
parent
5bbb5a1b74
commit
0097ffab19
|
@ -1,6 +1,6 @@
|
|||
#version 330
|
||||
|
||||
// pathfinder/demo2/cover.fs.glsl
|
||||
// pathfinder/demo3/resources/shaders/mask_tile.fs.glsl
|
||||
//
|
||||
// Copyright © 2018 The Pathfinder Project Developers.
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#version 330
|
||||
|
||||
// pathfinder/demo2/cover.vs.glsl
|
||||
// pathfinder/demo3/resources/shaders/mask_tile.vs.glsl
|
||||
//
|
||||
// Copyright © 2018 The Pathfinder Project Developers.
|
||||
//
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#version 330
|
||||
|
||||
// pathfinder/demo2/opaque.vs.glsl
|
||||
// pathfinder/demo3/resources/shaders/solid_tile.vs.glsl
|
||||
//
|
||||
// Copyright © 2018 The Pathfinder Project Developers.
|
||||
// Copyright © 2019 The Pathfinder Project Developers.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
|
|
|
@ -12,6 +12,8 @@ use clap::{App, Arg};
|
|||
use euclid::Size2D;
|
||||
use gl::types::{GLchar, GLfloat, GLint, GLsizei, GLsizeiptr, GLuint, GLvoid};
|
||||
use jemallocator;
|
||||
use pathfinder_geometry::point::Point2DF32;
|
||||
use pathfinder_geometry::transform::Transform2DF32;
|
||||
use pathfinder_renderer::builder::SceneBuilder;
|
||||
use pathfinder_renderer::gpu_data::{Batch, BuiltScene, SolidTileScenePrimitive};
|
||||
use pathfinder_renderer::paint::ObjectShader;
|
||||
|
@ -52,7 +54,8 @@ const FILL_COLORS_TEXTURE_WIDTH: u32 = 256;
|
|||
const FILL_COLORS_TEXTURE_HEIGHT: u32 = 256;
|
||||
|
||||
fn main() {
|
||||
let scene = load_scene();
|
||||
let options = Options::get();
|
||||
let base_scene = load_scene(&options);
|
||||
|
||||
let sdl_context = sdl2::init().unwrap();
|
||||
let sdl_video = sdl_context.video().unwrap();
|
||||
|
@ -68,7 +71,7 @@ fn main() {
|
|||
.build()
|
||||
.unwrap();
|
||||
|
||||
let gl_context = window.gl_create_context().unwrap();
|
||||
let _gl_context = window.gl_create_context().unwrap();
|
||||
gl::load_with(|name| sdl_video.gl_get_proc_address(name) as *const _);
|
||||
|
||||
let mut sdl_event_pump = sdl_context.event_pump().unwrap();
|
||||
|
@ -77,11 +80,19 @@ fn main() {
|
|||
let (drawable_width, drawable_height) = window.drawable_size();
|
||||
let mut renderer = Renderer::new(&Size2D::new(drawable_width, drawable_height));
|
||||
|
||||
let mut scale = 1.0;
|
||||
|
||||
while !exit {
|
||||
let mut scene = base_scene.clone();
|
||||
scene.transform(&Transform2DF32::from_scale(&Point2DF32::new(scale, scale)));
|
||||
scale -= 0.1;
|
||||
|
||||
let built_scene = build_scene(&scene, &options);
|
||||
|
||||
unsafe {
|
||||
gl::ClearColor(1.0, 1.0, 1.0, 1.0);
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
renderer.render_scene(&scene);
|
||||
renderer.render_scene(&built_scene);
|
||||
}
|
||||
|
||||
window.gl_swap_window();
|
||||
|
@ -97,37 +108,48 @@ fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
fn load_scene() -> BuiltScene {
|
||||
let matches = App::new("tile-svg")
|
||||
.arg(
|
||||
Arg::with_name("jobs")
|
||||
.short("j")
|
||||
.long("jobs")
|
||||
.value_name("THREADS")
|
||||
.takes_value(true)
|
||||
.help("Number of threads to use"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("INPUT")
|
||||
.help("Path to the SVG file to render")
|
||||
.required(true)
|
||||
.index(1),
|
||||
)
|
||||
.get_matches();
|
||||
let jobs: Option<usize> = matches
|
||||
.value_of("jobs")
|
||||
.map(|string| string.parse().unwrap());
|
||||
let input_path = PathBuf::from(matches.value_of("INPUT").unwrap());
|
||||
struct Options {
|
||||
jobs: Option<usize>,
|
||||
input_path: PathBuf,
|
||||
}
|
||||
|
||||
// Set up Rayon.
|
||||
let mut thread_pool_builder = ThreadPoolBuilder::new();
|
||||
if let Some(jobs) = jobs {
|
||||
thread_pool_builder = thread_pool_builder.num_threads(jobs);
|
||||
impl Options {
|
||||
fn get() -> Options {
|
||||
let matches = App::new("tile-svg")
|
||||
.arg(
|
||||
Arg::with_name("jobs")
|
||||
.short("j")
|
||||
.long("jobs")
|
||||
.value_name("THREADS")
|
||||
.takes_value(true)
|
||||
.help("Number of threads to use"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("INPUT")
|
||||
.help("Path to the SVG file to render")
|
||||
.required(true)
|
||||
.index(1),
|
||||
)
|
||||
.get_matches();
|
||||
let jobs: Option<usize> = matches
|
||||
.value_of("jobs")
|
||||
.map(|string| string.parse().unwrap());
|
||||
let input_path = PathBuf::from(matches.value_of("INPUT").unwrap());
|
||||
|
||||
// Set up Rayon.
|
||||
let mut thread_pool_builder = ThreadPoolBuilder::new();
|
||||
if let Some(jobs) = jobs {
|
||||
thread_pool_builder = thread_pool_builder.num_threads(jobs);
|
||||
}
|
||||
thread_pool_builder.build_global().unwrap();
|
||||
|
||||
Options { jobs, input_path }
|
||||
}
|
||||
thread_pool_builder.build_global().unwrap();
|
||||
}
|
||||
|
||||
fn load_scene(options: &Options) -> Scene {
|
||||
// Build scene.
|
||||
let usvg = Tree::from_file(&input_path, &UsvgOptions::default()).unwrap();
|
||||
let usvg = Tree::from_file(&options.input_path, &UsvgOptions::default()).unwrap();
|
||||
let scene = Scene::from_tree(usvg);
|
||||
|
||||
println!(
|
||||
|
@ -140,20 +162,23 @@ fn load_scene() -> BuiltScene {
|
|||
scene.paints.len()
|
||||
);
|
||||
|
||||
scene
|
||||
}
|
||||
|
||||
fn build_scene(scene: &Scene, options: &Options) -> BuiltScene {
|
||||
let (mut elapsed_object_build_time, mut elapsed_scene_build_time) = (0.0, 0.0);
|
||||
|
||||
let mut built_scene = BuiltScene::new(&scene.view_box);
|
||||
let z_buffer = ZBuffer::new(&scene.view_box);
|
||||
|
||||
let start_time = Instant::now();
|
||||
let built_objects = match jobs {
|
||||
let built_objects = match options.jobs {
|
||||
Some(1) => scene.build_objects_sequentially(&z_buffer),
|
||||
_ => scene.build_objects(&z_buffer),
|
||||
};
|
||||
elapsed_object_build_time += duration_to_ms(&(Instant::now() - start_time));
|
||||
|
||||
let start_time = Instant::now();
|
||||
built_scene = BuiltScene::new(&scene.view_box);
|
||||
let mut built_scene = BuiltScene::new(&scene.view_box);
|
||||
built_scene.shaders = scene.build_shaders();
|
||||
let mut scene_builder = SceneBuilder::new(built_objects, z_buffer, &scene.view_box);
|
||||
built_scene.solid_tiles = scene_builder.build_solid_tiles();
|
||||
|
@ -191,6 +216,7 @@ struct Renderer {
|
|||
solid_tile_program: SolidTileProgram,
|
||||
mask_tile_program: MaskTileProgram,
|
||||
area_lut_texture: Texture,
|
||||
#[allow(dead_code)]
|
||||
quad_vertex_positions_buffer: Buffer,
|
||||
fill_vertex_array: FillVertexArray,
|
||||
mask_tile_vertex_array: MaskTileVertexArray,
|
||||
|
@ -676,7 +702,9 @@ impl Uniform {
|
|||
|
||||
struct Program {
|
||||
gl_program: GLuint,
|
||||
#[allow(dead_code)]
|
||||
vertex_shader: Shader,
|
||||
#[allow(dead_code)]
|
||||
fragment_shader: Shader,
|
||||
}
|
||||
|
||||
|
|
|
@ -81,6 +81,17 @@ impl LineSegmentF32 {
|
|||
LineSegmentF32(mid_mid.as_f64x2().interleave(to_to.as_f64x2()).0.as_f32x4()))
|
||||
}
|
||||
|
||||
// Returns the left segment first, followed by the right segment.
|
||||
#[inline]
|
||||
pub fn split_at_x(&self, x: f32) -> (LineSegmentF32, LineSegmentF32) {
|
||||
let (min_part, max_part) = self.split(self.solve_t_for_x(x));
|
||||
if min_part.from_x() < max_part.from_x() {
|
||||
(min_part, max_part)
|
||||
} else {
|
||||
(max_part, min_part)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the upper segment first, followed by the lower segment.
|
||||
#[inline]
|
||||
pub fn split_at_y(&self, y: f32) -> (LineSegmentF32, LineSegmentF32) {
|
||||
|
@ -121,6 +132,16 @@ impl LineSegmentF32 {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn min_x(&self) -> f32 {
|
||||
f32::min(self.from_x(), self.to_x())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn max_x(&self) -> f32 {
|
||||
f32::max(self.from_x(), self.to_x())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn min_y(&self) -> f32 {
|
||||
f32::min(self.from_y(), self.to_y())
|
||||
|
|
|
@ -12,17 +12,19 @@
|
|||
|
||||
use crate::point::Point2DF32;
|
||||
use crate::segment::{Segment, SegmentFlags, SegmentKind};
|
||||
use crate::transform::Transform2DF32;
|
||||
use euclid::{Point2D, Rect};
|
||||
use lyon_path::PathEvent;
|
||||
use std::fmt::{self, Debug, Formatter};
|
||||
use std::mem;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Outline {
|
||||
pub contours: Vec<Contour>,
|
||||
bounds: Rect<f32>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Contour {
|
||||
points: Vec<Point2DF32>,
|
||||
flags: Vec<PointFlags>,
|
||||
|
@ -118,6 +120,11 @@ impl Outline {
|
|||
pub fn bounds(&self) -> &Rect<f32> {
|
||||
&self.bounds
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn transform(&mut self, transform: &Transform2DF32) {
|
||||
self.contours.iter_mut().for_each(|contour| contour.transform(transform));
|
||||
}
|
||||
}
|
||||
|
||||
impl Contour {
|
||||
|
@ -261,6 +268,13 @@ impl Contour {
|
|||
point_index + 1
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn transform(&mut self, transform: &Transform2DF32) {
|
||||
for point in &mut self.points {
|
||||
*point = transform.transform_point(point)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Contour {
|
||||
|
|
|
@ -59,6 +59,7 @@ pub struct TileObjectPrimitive {
|
|||
pub backdrop: i16,
|
||||
}
|
||||
|
||||
// FIXME(pcwalton): Move `subpx` before `px` and remove `repr(packed)`.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[repr(packed)]
|
||||
pub struct FillBatchPrimitive {
|
||||
|
|
|
@ -17,9 +17,10 @@ use crate::z_buffer::ZBuffer;
|
|||
use euclid::Rect;
|
||||
use hashbrown::HashMap;
|
||||
use pathfinder_geometry::outline::Outline;
|
||||
use pathfinder_geometry::transform::Transform2DF32;
|
||||
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Scene {
|
||||
pub objects: Vec<PathObject>,
|
||||
pub paints: Vec<Paint>,
|
||||
|
@ -96,9 +97,16 @@ impl Scene {
|
|||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn transform(&mut self, transform: &Transform2DF32) {
|
||||
// TODO(pcwalton): Transform bounds?
|
||||
for object in &mut self.objects {
|
||||
object.outline.transform(transform)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PathObject {
|
||||
outline: Outline,
|
||||
paint: PaintId,
|
||||
|
|
|
@ -177,7 +177,7 @@ impl<'o, 'z> Tiler<'o, 'z> {
|
|||
}
|
||||
|
||||
// Do final subtile fill, if necessary.
|
||||
debug_assert!(current_tile_x == segment_tile_x);
|
||||
debug_assert_eq!(current_tile_x, segment_tile_x);
|
||||
debug_assert!(current_tile_x < self.built_object.tile_rect.max_x());
|
||||
let segment_subtile_x =
|
||||
segment_x - (i32::from(current_tile_x) * TILE_WIDTH as i32) as f32;
|
||||
|
|
Loading…
Reference in New Issue