Encode stroke in scene

This just adds the first step of polyline stroking, which is adding it
to the scene. Also just a bit of cleaning up of dimensions into one
header file.
This commit is contained in:
Raph Levien 2020-04-24 13:06:47 -07:00
parent 7528eaff22
commit e1c0e448ef
11 changed files with 113 additions and 47 deletions

4
Cargo.lock generated
View file

@ -93,8 +93,7 @@ dependencies = [
[[package]]
name = "kurbo"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf50e17a1697110c694d47c5b1a6b64faf5eb3ffe5a286df23fb8cd516e33be6"
source = "git+https://github.com/linebender/kurbo?rev=7bd7e66bd137e757305d170a0f9f2b4f7beeb299#7bd7e66bd137e757305d170a0f9f2b4f7beeb299"
dependencies = [
"arrayvec",
]
@ -128,6 +127,7 @@ dependencies = [
name = "piet-gpu"
version = "0.1.0"
dependencies = [
"kurbo",
"piet",
"piet-gpu-hal",
"piet-gpu-types",

View file

@ -6,3 +6,7 @@ members = [
"piet-gpu-hal",
"piet-gpu-types"
]
# TODO: remove when the flatten feature is published
[patch.crates-io]
kurbo = { git = "https://github.com/linebender/kurbo", rev = "7bd7e66bd137e757305d170a0f9f2b4f7beeb299" }

View file

@ -13,6 +13,7 @@ path = "../piet-gpu-hal"
path = "../piet-gpu-types"
[dependencies]
kurbo = "0.5.11"
piet = "0.0.12"
png = "0.16.2"
rand = "0.7.3"

View file

@ -9,8 +9,8 @@ rule glsl
build image.spv: glsl image.comp | scene.h
build kernel1.spv: glsl kernel1.comp | scene.h tilegroup.h
build kernel1.spv: glsl kernel1.comp | scene.h tilegroup.h setup.h
build kernel3.spv: glsl kernel3.comp | scene.h tilegroup.h ptcl.h
build kernel3.spv: glsl kernel3.comp | scene.h tilegroup.h ptcl.h setup.h
build kernel4.spv: glsl kernel4.comp | ptcl.h
build kernel4.spv: glsl kernel4.comp | ptcl.h setup.h

View file

@ -28,13 +28,7 @@ layout(set = 0, binding = 1) buffer TilegroupBuf {
#include "scene.h"
#include "tilegroup.h"
// TODO: compute this
#define WIDTH_IN_TILEGROUPS 4
#define TILEGROUP_WIDTH_PX 512
#define TILEGROUP_HEIGHT_PX 16
#define TILEGROUP_INITIAL_ALLOC 1024
#include "setup.h"
#define MAX_STACK 8

View file

@ -24,19 +24,7 @@ layout(set = 0, binding = 2) buffer PtclBuf {
#include "tilegroup.h"
#include "ptcl.h"
// TODO: compute all these
#define WIDTH_IN_TILEGROUPS 4
#define WIDTH_IN_TILES 128
#define TILEGROUP_WIDTH_TILES 32
#define TILE_WIDTH_PX 16
#define TILE_HEIGHT_PX 16
// Must be the same as kernel1. Might be a good idea to move these particular
// constants to their own .h file.
#define TILEGROUP_INITIAL_ALLOC 1024
#define PTCL_INITIAL_ALLOC 4096
#include "setup.h"
void main() {
uint tile_ix = gl_GlobalInvocationID.y * WIDTH_IN_TILES + gl_GlobalInvocationID.x;

View file

@ -20,13 +20,7 @@ layout(set = 0, binding = 1) buffer ImageBuf {
#include "ptcl.h"
// TODO: make the image size dynamic.
#define IMAGE_WIDTH 2048
#define IMAGE_HEIGHT 1535
#define WIDTH_IN_TILES 128
#define PTCL_INITIAL_ALLOC 4096
#include "setup.h"
void main() {
uint tile_ix = gl_WorkGroupID.y * WIDTH_IN_TILES + gl_WorkGroupID.x;

Binary file not shown.

25
piet-gpu/shader/setup.h Normal file
View file

@ -0,0 +1,25 @@
// Various constants for the sizes of groups and tiles.
// Much of this will be made dynamic in various ways, but for now it's easiest
// to hardcode and keep all in one place.
// TODO: make the image size dynamic.
#define IMAGE_WIDTH 2048
#define IMAGE_HEIGHT 1536
// TODO: compute this
#define WIDTH_IN_TILEGROUPS 4
#define TILEGROUP_WIDTH_PX 512
#define TILEGROUP_HEIGHT_PX 16
#define TILEGROUP_INITIAL_ALLOC 1024
// TODO: compute all these
#define WIDTH_IN_TILES 128
#define TILEGROUP_WIDTH_TILES 32
#define TILE_WIDTH_PX 16
#define TILE_HEIGHT_PX 16
#define PTCL_INITIAL_ALLOC 4096

View file

@ -4,13 +4,12 @@ use std::path::Path;
use rand::{Rng, RngCore};
use piet::{Color, RenderContext};
use piet::kurbo::{Circle, Point};
use piet::{Color, RenderContext};
use piet_gpu_hal::vulkan::VkInstance;
use piet_gpu_hal::{CmdBuf, Device, MemFlags};
mod render_ctx;
use render_ctx::PietGpuRenderContext;
@ -27,8 +26,10 @@ fn render_scene(rc: &mut impl RenderContext) {
let mut rng = rand::thread_rng();
for _ in 0..N_CIRCLES {
let color = Color::from_rgba32_u32(rng.next_u32());
let center = Point::new(rng.gen_range(0.0, WIDTH as f64),
rng.gen_range(0.0, HEIGHT as f64));
let center = Point::new(
rng.gen_range(0.0, WIDTH as f64),
rng.gen_range(0.0, HEIGHT as f64),
);
let radius = rng.gen_range(0.0, 50.0);
let circle = Circle::new(center, radius);
rc.fill(circle, &color);

View file

@ -1,10 +1,10 @@
use std::borrow::Cow;
use piet_gpu_types::encoder::{Encode, Encoder};
use piet_gpu_types::encoder::{Encode, Encoder, Ref};
use piet_gpu_types::scene;
use piet_gpu_types::scene::{Bbox, PietCircle, PietItem, SimpleGroup};
use piet_gpu_types::scene::{Bbox, PietCircle, PietItem, PietStrokePolyLine, SimpleGroup};
use piet::kurbo::{Affine, Point, Rect, Shape};
use piet::kurbo::{Affine, PathEl, Point, Rect, Shape};
use piet::{
Color, Error, FixedGradient, Font, FontBuilder, HitTestPoint, HitTestTextPosition, ImageFormat,
@ -39,6 +39,8 @@ pub enum PietGpuBrush {
Gradient,
}
const TOLERANCE: f64 = 0.1;
impl PietGpuRenderContext {
pub fn new() -> PietGpuRenderContext {
let mut encoder = Encoder::new();
@ -104,7 +106,24 @@ impl RenderContext for PietGpuRenderContext {
fn clear(&mut self, _color: Color) {}
fn stroke(&mut self, _shape: impl Shape, _brush: &impl IntoBrush<Self>, _width: f64) {}
fn stroke(&mut self, shape: impl Shape, brush: &impl IntoBrush<Self>, width: f64) {
let bbox = shape.bounding_box();
let brush = brush.make_brush(self, || bbox).into_owned();
let path = shape.to_bez_path(TOLERANCE);
let (n_points, points) = flatten_shape(&mut self.encoder, path);
match brush {
PietGpuBrush::Solid(rgba_color) => {
let poly_line = PietStrokePolyLine {
rgba_color,
width: width as f32,
n_points,
points,
};
self.push_item(PietItem::Poly(poly_line), bbox);
}
_ => (),
}
}
fn stroke_styled(
&mut self,
@ -116,13 +135,7 @@ impl RenderContext for PietGpuRenderContext {
}
fn fill(&mut self, shape: impl Shape, brush: &impl IntoBrush<Self>) {
let dummy_closure = || Rect {
x0: 0.0,
x1: 0.0,
y0: 0.0,
y1: 0.0,
};
let brush = brush.make_brush(self, dummy_closure).into_owned();
let brush = brush.make_brush(self, || shape.bounding_box()).into_owned();
match shape.as_circle() {
Some(circle) => match brush {
@ -212,6 +225,45 @@ impl RenderContext for PietGpuRenderContext {
}
}
fn flatten_shape(
encoder: &mut Encoder,
path: impl Iterator<Item = PathEl>,
) -> (u32, Ref<scene::Point>) {
let mut points = Vec::new();
let mut start_pt = None;
let mut last_pt = None;
kurbo::flatten(path, TOLERANCE, |el| {
match el {
PathEl::MoveTo(p) => {
let scene_pt = to_scene_point(p);
start_pt = Some(clone_scene_pt(&scene_pt));
if !points.is_empty() {
points.push(scene::Point { xy: [std::f32::NAN, std::f32::NAN ]});
}
last_pt = Some(clone_scene_pt(&scene_pt));
points.push(scene_pt);
}
PathEl::LineTo(p) => {
let scene_pt = to_scene_point(p);
last_pt = Some(clone_scene_pt(&scene_pt));
points.push(scene_pt);
}
PathEl::ClosePath => {
if let (Some(start), Some(last)) = (start_pt.take(), last_pt.take()) {
if start.xy != last.xy {
points.push(start);
}
}
}
_ => (),
}
println!("{:?}", el);
});
let n_points = points.len() as u32;
let points_ref = points.encode(encoder).transmute();
(n_points, points_ref)
}
impl Text for PietGpuText {
type Font = PietGpuFont;
type FontBuilder = PietGpuFontBuilder;
@ -295,3 +347,10 @@ fn to_scene_point(point: Point) -> scene::Point {
xy: [point.x as f32, point.y as f32],
}
}
// TODO: allow #[derive(Clone)] in piet-gpu-derive.
fn clone_scene_pt(p: &scene::Point) -> scene::Point {
scene::Point {
xy: p.xy
}
}